题意是问所有前缀出现的次数和,mod10007;
想一想next数组代表什么意思,是从当前失配位置走到上一个匹配位置的后面,next[i]的值说明以当前位置为结尾,长度为next[i]的后缀,与以开头元素为起始,长度为next【i】
的前缀是相同的,那么方法就很容易了,对于每个j = i,沿着next【j】往前走,到0为止,记录走过的次数,就是前缀的出现次数。
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<map> #include<vector> #include<cmath> #include<set> using namespace std; const int maxn = 1e6+5; const int mod = 10007; char s[maxn]; vector<int> find_sub(char *pattern)//预处理next { int n = strlen(pattern); vector<int> next(n+1,0); for(int i = 1; i < n; ++i) { int j = i; while(j > 0){ j = next[j]; if(pattern[j] == pattern[i]){ next[i+1] = j+1; break; } } } return next; } int main() { // freopen("in","r",stdin); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); scanf("%s",s); vector<int> v = find_sub(s); int ans = 0; for(int i = 0; i < v.size(); ++i) { int j = i; while(j){ ans = (ans+1)%mod; j = v[j]; } } printf("%d\n",ans); } }
时间: 2024-10-26 04:48:35