Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define pb push_back
- #define mp make_pair
- #define ff first
- #define ss second
- #define xd puts("XD")
- #define endl puts("")
- #define ub upper_bound
- #define lb lower_bound
- #define MAXN 500005
- typedef long long int ll;
- int n, kon, l, wynik, gdzie, ile;
- char s[MAXN];
- ll H1=37, H2=41, h1[MAXN], h2[MAXN], pot1[MAXN], pot2[MAXN], M1=1000000009, M2=1000696969;
- bool czy[MAXN];
- int bns3(int pocz, int koniec)
- {
- int sr=(pocz+koniec)/2;
- ll hs1=h1[kon+sr]-h1[kon]+M1*2;
- ll hs2=h2[kon+sr]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[sr];
- ll w2=h2[sr];
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- bool joker=false;
- //printf ("hs1=%lld w1=%lld hs2=%lld w2=%lld\n", hs1, w1, hs2, w2);
- if (hs1==w1 && hs2==w2)
- {
- joker=true;
- }
- //printf ("bns3 pocz=%d koniec=%d sr=%d joker=%d\n", pocz, koniec, sr, joker);
- if (joker==false)
- {
- wynik=min(wynik, sr);
- }
- if (pocz<koniec)
- {
- if (joker==false)
- {
- return bns3(pocz, sr);
- }
- else
- {
- return bns3(sr+1, koniec);
- }
- }
- else
- {
- return wynik;
- }
- }
- int bns2(int pocz, int koniec, int k)
- {
- int sr=(pocz+koniec)/2;
- ll hs1=h1[sr];
- ll hs2=h2[sr];
- ll w1=h1[k+sr]-h1[k]+M1*2;
- ll w2=h2[k+sr]-h2[k]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[k];
- hs2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- bool joker=false;
- //printf ("hs1=%lld w1=%lld hs2=%lld w2=%lld\n", hs1, w1, hs2, w2);
- if (hs1==w1 && hs2==w2)
- {
- joker=true;
- }
- //printf ("bns2 pocz=%d koniec=%d sr=%d joker=%d\n", pocz, koniec, sr, joker);
- if (joker==false)
- {
- wynik=min(wynik, sr);
- }
- if (pocz<koniec)
- {
- if (joker==false)
- {
- return bns2(pocz, sr, k);
- }
- else
- {
- return bns2(sr+1, koniec, k);
- }
- }
- else
- {
- return wynik;
- }
- }
- int bns1(int pocz, int koniec, int k)
- {
- int sr=(pocz+koniec)/2;
- ll hs1=h1[sr];
- ll hs2=h2[sr];
- ll w1=h1[(gdzie-1)*k+sr]-h1[(gdzie-1)*k]+M1*2;
- ll w2=h2[(gdzie-1)*k+sr]-h2[(gdzie-1)*k]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[(gdzie-1)*k];
- hs2*=pot2[(gdzie-1)*k];
- hs1%=M1;
- hs2%=M2;
- bool joker=false;
- //printf ("hs1=%lld w1=%lld hs2=%lld w2=%lld\n", hs1, w1, hs2, w2);
- if (hs1==w1 && hs2==w2)
- {
- joker=true;
- }
- //printf ("bns1 pocz=%d koniec=%d sr=%d joker=%d\n", pocz, koniec, sr, joker);
- if (joker==false)
- {
- wynik=min(wynik, sr);
- }
- if (pocz<koniec)
- {
- if (joker==false)
- {
- return bns1(pocz, sr, k);
- }
- else
- {
- return bns1(sr+1, koniec, k);
- }
- }
- else
- {
- return wynik;
- }
- }
- int main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cin >> s;
- n=strlen(s);
- //printf ("n=%d\n", n);
- for (int i=n; i>=1; i--)
- {
- s[i]=s[i-1];
- }
- pot1[0]=pot2[0]=1;
- for (int i=1; i<=n; i++)
- {
- pot1[i]=pot1[i-1]*H1;
- pot1[i]%=M1;
- pot2[i]=pot2[i-1]*H2;
- pot2[i]%=M2;
- h1[i]=h1[i-1]+pot1[i]*(int(s[i])-96);
- h1[i]%=M1;
- h2[i]=h2[i-1]+pot2[i]*(int(s[i])-96);
- h2[i]%=M2;
- }
- for (int k=1; k<n; k++)
- {
- l=n/k;
- kon=l*k;
- //printf ("------------------------k=%d l=%d kon=%d------------------------------\n", k, l, kon);
- if (l==1)
- {
- //puts ("CASE 1");
- ll hs1=h1[n]-h1[kon]+M1*2;
- ll hs2=h2[n]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[n-kon];
- ll w2=h2[n-kon];
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("ROWNE");
- czy[k]=true;
- }
- else
- {
- //puts ("ROZNE");
- wynik=n+1;
- int gg=bns3(1, n-kon);
- //printf ("gg=%d\n", gg);
- hs1=h1[n]-h1[kon+gg]+M1*2;
- hs2=h2[n]-h2[kon+gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[n-kon]-h1[gg]+M1*2;
- w2=h2[n-kon]-h2[gg]+M2*2;
- w1%=M1;
- w2%=M2;
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- }
- else if (l==2)
- {
- //puts ("CASE 2");
- bool czy12, czy23, czy13;
- czy12=czy23=czy13=false;
- {
- ll hs1=h1[k];
- ll hs2=h2[k];
- ll w1=h1[2*k]-h1[k]+M1*2;
- ll w2=h2[2*k]-h2[k]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[k];
- hs2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- czy12=true;
- }
- }
- {
- ll hs1=h1[n]-h1[kon]+M1*2;
- ll hs2=h2[n]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[n-kon];
- ll w2=h2[n-kon];
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- czy13=true;
- }
- }
- {
- ll hs1=h1[n]-h1[kon]+M1*2;
- ll hs2=h2[n]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[n-kon+k]-h1[k]+M1*2;
- ll w2=h2[n-kon+k]-h2[k]+M2*2;
- w1%=M1;
- w2%=M2;
- w1*=pot1[kon-k];
- w2*=pot2[kon-k];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- czy23=true;
- }
- }
- //printf ("czy12=%d czy13=%d czy23=%d\n", czy12, czy13, czy23);
- if (czy12==true && czy13==true && czy23==true)
- {
- //puts ("WSZYSTKIE");
- czy[k]=true;
- }
- else if (czy12==true)
- {
- //puts ("BLAD W 3");
- wynik=n+1;
- int gg=bns3(1, n-kon);
- //printf ("gg=%d\n", gg);
- ll hs1=h1[n]-h1[kon+gg]+M1*2;
- ll hs2=h2[n]-h2[kon+gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[n-kon]-h1[gg]+M1*2;
- ll w2=h2[n-kon]-h2[gg]+M2*2;
- w1%=M1;
- w2%=M2;
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- else if (czy13==true || czy23==true)
- {
- //puts ("OK W 3");
- wynik=n+1;
- int gg=bns2(1, k, k);
- //printf ("gg=%d\n", gg);
- ll hs1=h1[k]-h1[gg]+M1*2;
- ll hs2=h2[k]-h2[gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- ll w1=h1[2*k]-h1[k+gg]+M1*2;
- ll w2=h2[2*k]-h2[k+gg]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[k];
- hs2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- }
- else
- {
- //puts ("CASE 3");
- gdzie=0;
- ll hs1=h1[k];
- ll hs2=h2[k];
- ll w1=h1[2*k]-h1[k]+M1*2;
- ll w2=h2[2*k]-h2[k]+M2*2;
- w1%=M1;
- w2%=M2;
- ll z1=h1[3*k]-h1[2*k]+M1*2;
- ll z2=h2[3*k]-h2[2*k]+M2*2;
- z1%=M1;
- z2%=M2;
- ll p1=-1, p2=-1;
- hs1*=pot1[2*k];
- hs2*=pot2[2*k];
- w1*=pot1[k];
- w2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- p1=hs1;
- p2=hs2;
- }
- if (hs1==z1 && hs2==z2)
- {
- p1=hs1;
- p2=hs2;
- }
- if (w1==z1 && w2==z2)
- {
- p1=w1;
- p2=w2;
- }
- //printf ("p1=%lld p2=%lld hs1=%lld w1=%lld z1=%lld hs2=%lld w2=%lld z2=%lld\n", p1, p2, hs1, w1, z1, hs2, w2, z2);
- for (int i=k; i<=kon; i+=k)
- {
- ll o1=p1, o2=p2;
- hs1=h1[i]-h1[i-k]+M1*2;
- hs2=h2[i]-h2[i-k]+M2*2;
- hs1%=M1;
- hs2%=M2;
- if (i==k)
- {
- hs1*=pot1[2*k];
- hs2*=pot2[2*k];
- hs1%=M1;
- hs2%=M2;
- }
- if (i==2*k)
- {
- hs1*=pot1[k];
- hs2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- }
- if (i>3*k)
- {
- p1*=pot1[i-3*k];
- p2*=pot2[i-3*k];
- p1%=M1;
- p2%=M2;
- }
- if (p1!=hs1 || p2!=hs2)
- {
- //printf ("PELNY OKRES NR %d JEST ZLY\n", i/k);
- if (gdzie==0)
- {
- gdzie=i/k;
- }
- else
- {
- gdzie=M2;
- }
- }
- p1=o1;
- p2=o2;
- }
- if (gdzie!=1)
- {
- hs1=h1[n]-h1[kon]+M1*2;
- hs2=h2[n]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[n-kon];
- w2=h2[n-kon];
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- }
- else
- {
- hs1=h1[n]-h1[kon]+M1*2;
- hs2=h2[n]-h2[kon]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[n-kon+k]-h1[k]+M1*2;
- w2=h2[n-kon+k]-h2[k]+M2*2;
- w1%=M1;
- w2%=M2;
- w1*=pot1[kon-k];
- w2*=pot2[kon-k];
- w1%=M1;
- w2%=M2;
- }
- if (hs1!=w1 || hs2!=w2)
- {
- //printf ("NIEPELNY JEST ZLY\n");
- if (gdzie==0)
- {
- gdzie=l+1;
- }
- else
- {
- gdzie=M2;
- }
- }
- if (gdzie==0)
- {
- czy[k]=true;
- }
- else if (gdzie<M2)
- {
- //printf ("BYL TYLKO JEDEN BLAD, W gdzie=%d\n", gdzie);
- if (gdzie==l+1)
- {
- //puts ("NIEPELNY OKRES");
- wynik=n+1;
- int gg=bns3(1, n-kon);
- //printf ("gg=%d\n", gg);
- hs1=h1[n]-h1[kon+gg]+M1*2;
- hs2=h2[n]-h2[kon+gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[n-kon]-h1[gg]+M1*2;
- w2=h2[n-kon]-h2[gg]+M2*2;
- w1%=M1;
- w2%=M2;
- w1*=pot1[kon];
- w2*=pot2[kon];
- w1%=M1;
- w2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- else
- {
- //puts ("NIEPELNY");
- wynik=n+1;
- int gg;
- if (gdzie<=2)
- {
- //puts ("<=2");
- gg=bns2(1, k, k);
- //printf ("gg=%d\n", gg);
- hs1=h1[k]-h1[gg]+M1*2;
- hs2=h2[k]-h2[gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[2*k]-h1[k+gg]+M1*2;
- w2=h2[2*k]-h2[k+gg]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[k];
- hs2*=pot2[k];
- hs1%=M1;
- hs2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- else
- {
- //puts (">3");
- gg=bns1(1, k, k);
- //printf ("gg=%d\n", gg);
- hs1=h1[k]-h1[gg]+M1*2;
- hs2=h2[k]-h2[gg]+M2*2;
- hs1%=M1;
- hs2%=M2;
- w1=h1[gdzie*k]-h1[(gdzie-1)*k+gg]+M1*2;
- w2=h2[gdzie*k]-h2[(gdzie-1)*k+gg]+M2*2;
- w1%=M1;
- w2%=M2;
- hs1*=pot1[(gdzie-1)*k];
- hs2*=pot2[(gdzie-1)*k];
- hs1%=M1;
- hs2%=M2;
- if (hs1==w1 && hs2==w2)
- {
- //puts ("OK");
- czy[k]=true;
- }
- }
- }
- }
- }
- }
- for (int i=1; i<=n; i++)
- {
- if (czy[i]==true)
- {
- ile++;
- }
- }
- printf ("%d\n", ile);
- for (int i=1; i<=n; i++)
- {
- if (czy[i]==true)
- {
- printf ("%d ", i);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement