BZOJ2803: [Poi2012]Prefixuffix

来源:互联网 发布:阿里域名备案 编辑:程序博客网 时间:2024/06/05 11:29

有个很厉害的性质,推出了这个就可以DP了

有了这个DP,就可以枚举找一个最大值了
这题好像需要双hash

code:

#include<map>#include<set>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;void read(int &x){    char c;    while(!((c=getchar())>='0'&&c<='9'));    x=c-'0';    while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';}void up(int &x,int y){if(x<y)x=y;}const int maxn = 1100000;const ll Mod=1e9+7;char str[maxn];int f[maxn];ll h[maxn],hk=233,h2[maxn],hk2=1e8+7;ll pw[maxn],pw2[maxn];int n,m;bool judge(int l,int r,int l2,int r2){    ll s1=h[r]-h[l-1]*pw[r-l+1];    ll s2=h[r2]-h[l2-1]*pw[r2-l2+1];    if(s1!=s2) return false;    s1=h2[r]-h2[l-1]*pw2[r-l+1]%Mod;    s2=h2[r2]-h2[l2-1]*pw2[r-l+1]%Mod;    s1=(s1%Mod+Mod)%Mod;    s2=(s2%Mod+Mod)%Mod;    return s1==s2;}void g_f(){    int mi=n>>1; int k=0;    for(int i=mi;i>=1;i--)    {        k+=2; while(i+k-1>mi)k--;        while(k&&!judge(i,i+k-1,n-i+1-k+1,n-i+1))             k--;        f[i]=k;    }}int main(){    read(n);    scanf("%s",str+1);    for(int i=1;i<=n;i++) h[i]=h[i-1]*hk+str[i]-'a';    for(int i=1;i<=n;i++) h2[i]=(h2[i-1]*hk2+str[i]-'a')%Mod;    pw[0]=1ll; for(int i=1;i<=n;i++) pw[i]=pw[i-1]*hk;    pw2[0]=1ll; for(int i=1;i<=n;i++) pw2[i]=pw2[i-1]*hk2%Mod;    g_f();    int L=0; int mi=n>>1;    for(int i=n;i>=n-mi+1;i--)        if(judge(i,n,1,n-i+1)) up(L,(n-i+1)+f[n-i+2]);    printf("%d\n",L);    return 0;}
0 0
原创粉丝点击