432D - Prefixes and Suffixes(kmp + dp)

原题链接

题意:给你一个字符串s,让你求出一个前缀和后缀相等,并在字符串s中出现的次数。

解法:kmp,对于kmp中的next数组next[j]表示在模板串s[1,j]中前缀和后缀相同的最大长度。那么我们就可以通过kmp的next数组进行匹配。

next[len]获得的就是 前缀1-next[len]匹配的后缀len-next[len]+1。

next[next[len]]表示前缀子串1-next[next[len]]匹配的n-next[next[len]]+1-len后缀,之后通过这个性质,我们可以利用这个来通过dp进行计数,dp(i)表示字符串在字符串s中出现的次数

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define sc scanf
#define pr printf
#define INF 0x3f3f3f3f
const int maxn = 1e5 + 10;
int dp[maxn],Len[maxn],Next[maxn];
char str[maxn]; 
int top;
void get_next(int len){
	for(int i = 2,j = 0; i <= len; i++){
		while(j && str[i] != str[j + 1])j = Next[j];
		if(str[i] == str[j + 1])j++;
		Next[i] = j;
	}
}
void solve(){
     scanf("%s",str+1);
     int len = strlen(str + 1);
     get_next(len);
     //get_next可以获得next[i]表示 str中以i结尾的非前缀子串 和 str的前缀 能够匹配的最大长度
	 //那么next[len]获得的就是 1-next[len] ... 后缀len-next[len]+1 ---- len
	for(int i = len; i >= 1; i = Next[i]){
		Len[++top] = i;
	}
	for(int i = len;i >= 1; i--){
		dp[Next[i]] += ++dp[i];
	}
	printf("%d\n",top);
	for(int i = top; i >= 1; i--){
		printf("%d %d\n",Len[i],dp[Len[i]]);
	}
}
int main(){
//	freopen("2.in","r",stdin);
//	IOS; 
	int t;
	t = 1;
//	sc("%d",&t);
	while(t--)
	solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值