题意:给你一个字符串 问你 他的所有前缀 在当前字符串出现的总次数
思路:本来是想 每个前缀都去匹配一次 当然会TLE 所以仔细想想 next数组 不就是前缀数组的匹配情况吗
所以 只要next数组>0我们就可以在总数上+1再加上非真前缀数即可
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=10007; int nextt[200007]; int n; void getnext(string s){ nextt[1]=0; for(int i=2,j=0;i<=n;i++){ while(j>0&&s[i-1]!=s[j]) j=nextt[j]; if(s[i-1]==s[j]) j++; nextt[i]=j; } } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ string s; cin>>n>>s; getnext(s); int ans=n; //非真前缀数 for(int i=1;i<=n;i++){ ans=(ans+(nextt[i]==0?0:1))%mod; //如果没有前后缀相同就不处理 } cout<<ans<<endl; } return 0; }
hdu 3336 Count the string(kmp)
原文:https://www.cnblogs.com/wmj6/p/10500744.html