3336 (Next陣列+dp)
阿新 • • 發佈:2018-12-20
Count the stringHDU - 3336
題意:給定字串s,求s的所有字首作為子串在s中出現的次數和。
思路:考慮dp
dp[i] 表示以第i個字母結尾的所有後綴與s的字首的匹配次數。
按照最暴力的想法來做的話,肯定我得列舉以第i個字母結尾的每個字尾。
其實也可以這樣想:dp[i] 等於s(0,i)最長字尾對結果的貢獻加1。然後又kmp裡Next陣列可以得知,s(0,i)的最長字尾等於Next[i]對應的s的字首。
由此可得:dp[i] = dp[Next[i]]+1; dp[0] = 0;
吐槽:此題資料太水。。。
#include <bits/stdc++.h> using namespace std; const int mod = 10007; char s[2000005]; int dp[2000005],Next[2000005]; void getNext(char s[]) { int len = strlen(s),i = 0; int k = -1; Next[0] = -1; while(i < len) { if(k == -1 || s[i] == s[k]) { Next[++i] = ++k; } else k = Next[k]; } } int main() { int t; cin >> t; while(t--) { int n; scanf("%d",&n); scanf("%s",s); getNext(s); dp[0] = 0; int ans = 0; for(int i = 1; i <= n; i++) { dp[i] = dp[Next[i]]+1; dp[i] %= mod; ans += dp[i]; ans %= mod; } printf("%d\n",ans); } return 0; }