【hash】珍珠

【来源】

https://loj.ac/problem/2427

【参考博客】
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 }
View Code

 

转载于:https://www.cnblogs.com/Osea/p/11324815.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值