纪中OJ 5178 【NOIP2017提高组模拟6.28】So many prefix?

KMP+前缀和

考场上没想到,打了一个AC自动机,水到了27.3分(十一组数据)

然后我们来看正解

首先显然的是从第一位开始,每个偶数位对应的前缀一定是一个答案,那我们记f[i]=1(i%2==0)

然后我们考虑KMP的过程,后面串匹配前缀,所以如果他能匹配到一个偶数,也就是说nxt[j]=i(i%2==0),那么我们就可以发现这个字符串对应的肯定是一个长度为偶数的前缀,那么直接累加就好了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=200010;
char s[M];
int nxt[M],f[M],n,k,ans;
signed main() 
{
  	scanf("%s",s+1);n=strlen(s+1);
  	for(int i=2; i<=n;i++) 
  	{
    	while(k&&s[k+1]!=s[i]) k=nxt[k];
    	if(s[k+1]==s[i]) nxt[i]=++k;
  	}
  	for(int i=2;i<=n; i++) 
  	{
    	if(i%2==0) f[i]++;
    	f[i]+=f[nxt[i]];
    	ans+=f[i];
  	}
  	printf("%d",ans);
  	return 0;
}

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/81605485