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

链接:

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

题解:

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

证明:

现在让我们来反证一下这个性质:
下图有四种情况,f[i]为红色, f[i-1]为全图。
bzoj2803性质证明
显然无论何时,f[i-1]对应图去掉两侧点,皆可以保证是一个f[i]。
所以 fi1<=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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值