前缀和(和前缀和并没有关系)

给你一个字符串,求所有长度为偶数的前缀在整个字符串出现的次数和。len<=200000

 

拿到这道题,看到前缀,首先想KMP,我们发现对于nex[i] , s[1~nex[i]] 与 s[i-nex[i]+1~i] 是相等的,于是我们可以直接让ans[nex[i]]+=ans[i],将i的贡献累计到nex[i]中

倒序枚举,将后面的答案一直向前累加即可。

正确性并不显然,但有些东西就是那么玄学。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200010
using namespace std;
char s[N];
int nex[N],len,p[N],ans;
int main(){
    scanf("%s",s+1);len=strlen(s+1);nex[1]=0;
    for(int i=2,j=0;i<=len;i++){
        while(j && s[j+1]!=s[i]) j=nex[j];
        if(s[j+1]==s[i]) j++;
        nex[i]=j;
    }
    for(int i=1;i<=len;i++) p[i]=1;
    for(int i=len;i>=1;i--) p[nex[i]]+=p[i];
    for(int i=1;i<=len;i++) if(i%2==0) ans+=p[i];
    printf("%d\n",ans);
}

 

posted @ 2019-10-14 14:50  dzzx_Syh  阅读(198)  评论(0编辑  收藏  举报