#include<bits/stdc++.h>
using namespace std;
#define len 7
int base=10;
int power[len];
void init()
{
power[0]=1;
for(int i=1;i<len;i++)
{
power[i]=power[i-1]*base;
}
}
int get_index(char ch)
{
return ch-'0';
}
void prefixHash(string s,vector<int> &ph)
{
int n=ph.size();
ph[0]=get_index(s[0]);
for(int i=1;i<n;i++)
{
ph[i]=ph[i-1]*base+get_index(s[i]);
}
}
int calcHash(int l,int r,vector<int> &ph)
{
if(l==0) return ph[r];
return ph[r]-(ph[l-1]*power[r-l+1]);
}
int main()
{
init();
//string s="123456";
string txt="1211212133333333333";
string pat="121";
int n=txt.size(),m=pat.size();
vector<int> ph1(n),ph2(m);
prefixHash(txt,ph1);
prefixHash(pat,ph2);
for(int i=0;i+m<=n;i++) /// i=3
{
int x=calcHash(i,i+m-1,ph1);
int y=calcHash(0,2,ph2);
if(x==y)
{
cout << "Found " << pat << " at i=" << i << endl;
}
}
//for(int i=0;i<n;i++) cout << ph[i] << endl;
//cout << calcHash(2,4,ph);
return 0;
}
/**
12112121
**/
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIGxlbiA3CmludCBiYXNlPTEwOwppbnQgcG93ZXJbbGVuXTsKCnZvaWQgaW5pdCgpCnsKICAgIHBvd2VyWzBdPTE7CiAgICBmb3IoaW50IGk9MTtpPGxlbjtpKyspCiAgICB7CiAgICAgICAgcG93ZXJbaV09cG93ZXJbaS0xXSpiYXNlOwogICAgfQp9CgppbnQgZ2V0X2luZGV4KGNoYXIgY2gpCnsKICAgIHJldHVybiBjaC0nMCc7Cn0KCnZvaWQgcHJlZml4SGFzaChzdHJpbmcgcyx2ZWN0b3I8aW50PiAmcGgpCnsKICAgIGludCBuPXBoLnNpemUoKTsKICAgIHBoWzBdPWdldF9pbmRleChzWzBdKTsKICAgIGZvcihpbnQgaT0xO2k8bjtpKyspCiAgICB7CiAgICAgICAgcGhbaV09cGhbaS0xXSpiYXNlK2dldF9pbmRleChzW2ldKTsKICAgIH0KfQoKaW50IGNhbGNIYXNoKGludCBsLGludCByLHZlY3RvcjxpbnQ+ICZwaCkKewogICAgaWYobD09MCkgcmV0dXJuIHBoW3JdOwogICAgcmV0dXJuIHBoW3JdLShwaFtsLTFdKnBvd2VyW3ItbCsxXSk7Cn0KCmludCBtYWluKCkKewogICAgaW5pdCgpOwogICAgLy9zdHJpbmcgcz0iMTIzNDU2IjsKICAgIHN0cmluZyB0eHQ9IjEyMTEyMTIxMzMzMzMzMzMzMzMiOwogICAgc3RyaW5nIHBhdD0iMTIxIjsKICAgIGludCBuPXR4dC5zaXplKCksbT1wYXQuc2l6ZSgpOwoKICAgIHZlY3RvcjxpbnQ+IHBoMShuKSxwaDIobSk7CiAgICBwcmVmaXhIYXNoKHR4dCxwaDEpOwogICAgcHJlZml4SGFzaChwYXQscGgyKTsKCgogICAgZm9yKGludCBpPTA7aSttPD1uO2krKykgLy8vIGk9MwogICAgewogICAgICAgIGludCB4PWNhbGNIYXNoKGksaSttLTEscGgxKTsKICAgICAgICBpbnQgeT1jYWxjSGFzaCgwLDIscGgyKTsKICAgICAgICBpZih4PT15KQogICAgICAgIHsKICAgICAgICAgICAgY291dCA8PCAiRm91bmQgIiA8PCBwYXQgPDwgIiBhdCBpPSIgPDwgaSA8PCBlbmRsOwogICAgICAgIH0KICAgIH0KICAgIC8vZm9yKGludCBpPTA7aTxuO2krKykgY291dCA8PCBwaFtpXSA8PCBlbmRsOwogICAgLy9jb3V0IDw8IGNhbGNIYXNoKDIsNCxwaCk7CgoKCgogICAgcmV0dXJuIDA7Cn0KCi8qKgoxMjExMjEyMQoqKi8K