【来源】
【参考博客】
LOJ#2427. 「POI2010」珍珠项链 Beads
【题解】:
复杂度计算:
暴力枚举k每次计算是n/2+n/3+n/4+...+1的,用调和级数算是?(?????)的
头尾给hash一遍,然后存放到set里面去重。
所以就是O(nlog n logn )
【代码】:
1 #include<set> 2 #include<cstdio> 3 #include<algorithm> 4 5 const int N = 2e5+100; 6 using namespace std; 7 8 typedef unsigned long long ULL ; 9 10 ULL h1[N],h2[N],p[N],base=13331; 11 set<ULL> S ; 12 int str[N],Ans[N],cnt,n,res,t; 13 14 void Get_Hash(){ 15 p[0] = 1 ; 16 for(int i=1;i<=n;i++) { 17 p[i] = p[i - 1] * base ; 18 h1[i] = h1[i-1] * base + str[i] ; 19 } 20 for(int i=n;i>=1;i--){ 21 h2[i] = h2[i+1] * base + str[i] ; 22 } 23 } 24 25 int calc1(int L,int R ){ 26 return h1[R] - h1[L-1] * p[R-L+1] ; 27 } 28 int calc2(int L,int R ){ 29 return h2[L] - h2[R+1] * p[R-L+1] ; 30 } 31 32 int Solve( int x ){ 33 S.clear() ; 34 ULL tmp ; 35 for(int i=1;i+x-1<=n;i+=x){ 36 tmp = min( calc1(i,i+x-1) , calc2(i,i+x-1) ); 37 S.insert(tmp); 38 } 39 return (int)S.size(); 40 } 41 int main() 42 { 43 scanf("%d",&n); 44 for( int i = 1 ; i<=n ; i++ ) scanf("%llu",&str[i]); 45 Get_Hash() ; 46 for(int i=1;i<=n;i++){ 47 t = Solve(i); 48 if( t > res ){ 49 res = t ; 50 cnt = 0; 51 } 52 if( t == res ){ 53 Ans[cnt++] = i ; 54 } 55 } 56 printf("%d %d\n",res,cnt); 57 for(int i=0;i<cnt;i++){ 58 printf("%d%c",Ans[i],i==cnt-1?'\n':' '); 59 } 60 return 0 ; 61 62 }