码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ2803】【Poi2012】Prefixuffix hash+推性质

时间:2015-05-16 16:35:15      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:bzoj2803   poi2012   prefixuffi   hash   推性质   

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/45768837");
}

题解:

首先我们如果设原串为串[ 1,n ]
然后 fi 表示串[ i+1,n?i ]中最长的串长使得串[ i+1,i+fi ]==串[n?i?fi+1,n?i]
这时存在一个性质 fi?1<=fi+2
然后就可以线性递推啦!

证明:

现在让我们来反证一下这个性质:
下图有四种情况,f[i]为红色, f[i-1]为全图。
技术分享
显然无论何时,f[i-1]对应图去掉两侧点,皆可以保证是一个f[i]。
所以fi?1<=fi+2

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1001000
#define mod 1000000009
#define base 1000000007
using namespace std;
int n,ans;
char s[N];
long long sum[N],hash[N],pw[N];
long long gethash(int l,int r)
{return (hash[r]+mod-hash[l-1]*pw[r-l+1]%mod)%mod;}
int main()
{
    freopen("test.in","r",stdin);

    int i,j,k;

    scanf("%d",&n);
    for(pw[0]=i=1;i<=n;i++)pw[i]=(long long)pw[i-1]*base%mod;
    scanf("%s",s+1);
    for(i=1;i<=n;i++)
    {
        hash[i]=(hash[i-1]*base%mod+s[i])%mod;
        sum[i]=sum[i-1]+s[i];
    }
    for(i=n>>1,j=0;~i;i--)
        if(sum[i]==sum[n]-sum[n-i])
            if(gethash(1,i)==gethash(n-i+1,n))
                for(j=min(n/2-i,j+2);j>=0;j--)
                    if(sum[i+j]-sum[i]==sum[n-i]-sum[n-i-j])
                        if(gethash(i+1,i+j)==gethash(n-i-j+1,n-i))
                            {ans=max(ans,i+j);break;}
    printf("%d\n",ans);
    return 0;
}

【BZOJ2803】【Poi2012】Prefixuffix hash+推性质

标签:bzoj2803   poi2012   prefixuffi   hash   推性质   

原文地址:http://blog.csdn.net/vmurder/article/details/45768837

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!