This documentation is automatically generated by online-judge-tools/verification-helper
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T,T MOD,T B>
struct RollingHash{
using ll = long long;
vector<T> hash,po;
RollingHash(vector<T> vs){init(vs);}
RollingHash(string &s){
vector<T> vs;
for(char c:s) vs.emplace_back(c);
init(vs);
}
void init(vector<T> vs){
int n=vs.size();
hash.assign(n+1,0);
po.assign(n+1,1);
for(int i=0;i<n;i++){
hash[i+1]=((ll)hash[i]*B+vs[i])%MOD;
po[i+1]=(ll)po[i]*B%MOD;
}
}
//S[l, r)
T find(int l,int r){
T res=(ll)hash[r]+MOD-(ll)hash[l]*po[r-l]%MOD;
return res>=MOD?res-MOD:res;
}
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
return 0;
}
#endif
#line 1 "string/rollinghash.cpp"
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T,T MOD,T B>
struct RollingHash{
using ll = long long;
vector<T> hash,po;
RollingHash(vector<T> vs){init(vs);}
RollingHash(string &s){
vector<T> vs;
for(char c:s) vs.emplace_back(c);
init(vs);
}
void init(vector<T> vs){
int n=vs.size();
hash.assign(n+1,0);
po.assign(n+1,1);
for(int i=0;i<n;i++){
hash[i+1]=((ll)hash[i]*B+vs[i])%MOD;
po[i+1]=(ll)po[i]*B%MOD;
}
}
//S[l, r)
T find(int l,int r){
T res=(ll)hash[r]+MOD-(ll)hash[l]*po[r-l]%MOD;
return res>=MOD?res-MOD:res;
}
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
return 0;
}
#endif