#include<bits/stdc++.h>
using namespace std;
#define len 9
#define mod 1000000007
int base=10;
int power[len];
void init()
{
power[0]=1;
for(int i=1;i<len;i++)
{
power[i]=(power[i-1]*base)%mod;
}
}
int getindex(char ch)
{
return ch-'0';
}
void prefixHash(string s,vector<int> &ph)
{
int n=ph.size();
ph[0]=getindex(s[0]);
for(int i=1;i<n;i++)
{
ph[i]=(((ph[i-1]*base)%mod)+getindex(s[i]))%mod;
}
}
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])%mod))%mod;
}
int main()
{
init();
//string s="123456";
string txt="22212121333333333333333333333333";
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,i+1,...,i+m-1
{
int x=calcHash(i,i+m-1,ph1); /// txt[i to t+m-1]
int y=calcHash(0,2,ph2); /// pat[0 to 2]
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
**/
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIGxlbiA5CiNkZWZpbmUgbW9kIDEwMDAwMDAwMDcKaW50IGJhc2U9MTA7CmludCBwb3dlcltsZW5dOwoKdm9pZCBpbml0KCkKewogICAgcG93ZXJbMF09MTsKICAgIGZvcihpbnQgaT0xO2k8bGVuO2krKykKICAgIHsKICAgICAgICBwb3dlcltpXT0ocG93ZXJbaS0xXSpiYXNlKSVtb2Q7CiAgICB9Cn0KCmludCBnZXRpbmRleChjaGFyIGNoKQp7CiAgICByZXR1cm4gY2gtJzAnOwp9Cgp2b2lkIHByZWZpeEhhc2goc3RyaW5nIHMsdmVjdG9yPGludD4gJnBoKQp7CiAgICBpbnQgbj1waC5zaXplKCk7CiAgICBwaFswXT1nZXRpbmRleChzWzBdKTsKICAgIGZvcihpbnQgaT0xO2k8bjtpKyspCiAgICB7CiAgICAgICAgcGhbaV09KCgocGhbaS0xXSpiYXNlKSVtb2QpK2dldGluZGV4KHNbaV0pKSVtb2Q7CiAgICB9Cn0KCmludCBjYWxjSGFzaChpbnQgbCxpbnQgcix2ZWN0b3I8aW50PiAmcGgpCnsKICAgIGlmKGw9PTApIHJldHVybiBwaFtyXTsKICAgIHJldHVybiAocGhbcl0tKChwaFtsLTFdKnBvd2VyW3ItbCsxXSklbW9kKSklbW9kOwp9CgppbnQgbWFpbigpCnsKICAgIGluaXQoKTsKICAgIC8vc3RyaW5nIHM9IjEyMzQ1NiI7CiAgICBzdHJpbmcgdHh0PSIyMjIxMjEyMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMyI7CiAgICBzdHJpbmcgcGF0PSIxMjEiOwogICAgaW50IG49dHh0LnNpemUoKSxtPXBhdC5zaXplKCk7CgogICAgdmVjdG9yPGludD4gcGgxKG4pLHBoMihtKTsKICAgIHByZWZpeEhhc2godHh0LHBoMSk7CiAgICBwcmVmaXhIYXNoKHBhdCxwaDIpOwoKCiAgICBmb3IoaW50IGk9MDtpK208PW47aSsrKSAvLy8gaSxpKzEsLi4uLGkrbS0xCiAgICB7CiAgICAgICAgaW50IHg9Y2FsY0hhc2goaSxpK20tMSxwaDEpOyAvLy8gdHh0W2kgdG8gdCttLTFdCiAgICAgICAgaW50IHk9Y2FsY0hhc2goMCwyLHBoMik7ICAgICAvLy8gcGF0WzAgdG8gMl0KICAgICAgICBpZih4PT15KQogICAgICAgIHsKICAgICAgICAgICAgY291dCA8PCAiRm91bmQgIiA8PCBwYXQgPDwgIiBhdCBpPSIgPDwgaSA8PCBlbmRsOwogICAgICAgIH0KICAgIH0KICAgIC8vZm9yKGludCBpPTA7aTxuO2krKykgY291dCA8PCBwaFtpXSA8PCBlbmRsOwogICAgLy9jb3V0IDw8IGNhbGNIYXNoKDIsNCxwaCk7CgogICAgcmV0dXJuIDA7Cn0KCi8qKgoxMjExMjEyMQoqKi8K