【题解】Luogu P3546 [POI2012] PRE-prefixuffix 哈希

我是个菜鸡我不会哈希QwQ

 

转化题意:求最长的相同前缀后缀

发现对于一个循环同构串类似于$abcdxxxxabcd > bcdxxxabc$

有$f[i]>=f[i-1]-2$

也就是$f[i-1]<=f[i]-2$

满足单调性,倒序枚举$i$同时判断可行性

这题好像必须双哈希

好吧这题不用双哈希是我太菜了QAQ

取模一定要+mod%mod+mod%mod!!!

 

code

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int base1=233;
 5 const int base2=2333;
 6 const int mod1=1e8+9;
 7 const int mod2=1e8+7;
 8 const int N=1e6+10;
 9 ll h1[N],h2[N],p1[N],p2[N];
10 char s[N];
11 int n;
12 inline ll H1(int l,int r){
13     return ((h1[r]-h1[l-1]*p1[r-l+1]+mod1)%mod1+mod1)%mod1;
14 }
15 inline ll H2(int l,int r){
16     return ((h2[r]-h2[l-1]*p2[r-l+1]+mod2)%mod2+mod2)%mod2;
17 }
18 inline bool check(int l1,int r1,int l2,int r2){
19     return H1(l1,r1)==H1(l2,r2)&&H2(l1,r1)==H2(l2,r2);
20 }
21 int main(){
22     scanf("%d%s",&n,s+1);
23     p1[0]=p2[0]=1;
24     for(int i=1;i<=n;i++){
25         p1[i]=p1[i-1]*base1%mod1;
26         p2[i]=p2[i-1]*base2%mod2;
27         h1[i]=(h1[i-1]*base1+s[i])%mod1;
28         h2[i]=(h2[i-1]*base2+s[i])%mod2;
29     }
30     int len=n>>1,pos=0,ans=0;
31     for(int i=len;i;i--,pos=min(len-i,pos+2)){
32         if(check(1,i,n-i+1,n)){
33             while(pos && !check(i+1,i+pos,n-i-pos+1,n-i))pos--;
34             ans=max(ans,pos+i);
35         }
36     }
37     printf("%d\n",ans);
38     return 0;
39 }
View Code

 

posted @ 2019-10-21 08:24  喵の耳  阅读(177)  评论(0编辑  收藏  举报