num数组让记录前缀后缀相同且不重复的数的个数,因为有限制条件,前后不能重复,所以匹配的时候如果有重复的也算是匹配失败。
然后是记录方案,考虑在没有约束条件时,记录方案时每次可以从上次失配的地方转移,有约束条件是同理。
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int n, m;
char a1[1000010];
int f[1000010], num[1000010];
inline int mul(int a, int b){
int ans = 0;
for(;b;b>>=1,a=(a*2)%mod) if(b&1) ans = (ans+a)%mod;
return ans;
}
int main(){
scanf("%d", &n);
while(n --){
scanf("%s", a1+1);
m = strlen(a1+1);
for(int i = 1; i <= m; i ++) f[i]=0;
int p = 0, ans = 1;
num[1] = 1;
for(int i = 2; i <= m; i ++){
while(p && a1[p+1]!=a1[i]) p = f[p];
if(a1[p+1] == a1[i]) p ++;
f[i] = p;
num[i] = num[p]+1;
}
p = 0;
for(int i = 2; i <= m; i ++){
while(p && (a1[p+1]!=a1[i] || i<2*p+2)) p = f[p];
if(a1[p+1] == a1[i]) p ++;
ans = mul(ans, num[p]+1);
}
printf("%d\n", ans);
}
return 0;
}

本文介绍了一种用于字符串匹配的算法,该算法可以计算出在给定限制条件下,字符串前缀与后缀相匹配但不重复的子串数量。通过记录不同长度下匹配成功的状态,实现了对满足特定条件的字符串匹配方案进行计数。
2187

被折叠的 条评论
为什么被折叠?



