前缀和(和前缀和并没有关系)
给你一个字符串,求所有长度为偶数的前缀在整个字符串出现的次数和。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); }