【来源】
【参考博客】
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 }
