标签:
hdu 3336(说实话理解得马马虎虎。。。)
题目:给出一个字符串,问该字符串的每个前缀在字符串中出现的次数之和。
思路:需要对next数组有足够的理解。设dp[i]表示以i结尾的字符串中出现的总次数(答案),那么首先在next[i]到i之间的前缀不会是对应的后缀,所以该长度的串数量恰好是dp[next[i]]+1。
/* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxlen=1e6+300; int fail[maxlen]; int T; void getFeil(char *s,int *f){ int len=strlen(s); int i=0,j=f[0]=-1; while(i<len){ while(j!=-1&&s[j]!=s[i]) j=f[j]; f[++i]=++j; } } const int mod=10007; int n; char r[maxlen]; int dp[maxlen]; int main(){ freopen("/home/files/CppFiles/in","r",stdin); //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); cin>>T; while(T--){ scanf("%d %s",&n,r); getFeil(r,fail); int len=strlen(r); dp[0]=0; int ans=0; for(int i=1;i<=len;i++){ dp[i]=dp[fail[i]]; dp[i]++; dp[i]%=mod; ans+=dp[i]; ans%=mod; } cout<<ans<<endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/Cw-trip/p/4824919.html