洛谷2375 【NOI2014】动物园(KMP)

版权声明:欢迎转载!请注明出处!qwq https://blog.csdn.net/g21glf/article/details/85316199

传送门

【题目分析】

nxt数组就是存储的失配位置,所以只用根据题目意思,求出每个位置的nxt并一直跳直到这个前(后)缀长度小于串长的一半即可统计答案,记得+1。

【代码~】

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e6+10;
const int MOD=1e9+7;

char s[MAXN];
int n;
int nxt[MAXN];
LL cnt[MAXN];
LL ans;

void calc_nxt(){
	int k=0;
	cnt[1]=1;
	int len=strlen(s+1);
	for(int i=2;i<=len;++i){
		while(k&&s[i]!=s[k+1]){
			k=nxt[k];
		}
		if(s[i]==s[k+1])
		  k++;
		nxt[i]=k;
		cnt[i]=cnt[k]+1;
	}
}

LL calc(){
	int k=0;
	LL ret=1;
	int len=strlen(s+1);
	for(int i=2;i<=len;++i){
		while(k&&s[i]!=s[k+1])
		  k=nxt[k];
		if(s[i]==s[k+1])
		  k++;
		while(k*2>i)
		  k=nxt[k];
		ret*=cnt[k]+1;
		ret%=MOD;
	}
	return ret;
}

int main(){
	cin>>n;
	for(int i=1;i<=n;++i){
		memset(nxt,0,sizeof(nxt));
		memset(cnt,0,sizeof(cnt));
		scanf("%s",s+1);
		calc_nxt();
		cout<<calc()<<'\n';
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/85316199