codeforces432D Prefixes and Suffixes(kmp+dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
You have a string s = s1s2...s|s|, where |s| is the length of string s, and si its i-th character.
Let's introduce several definitions:
- A substring s[i..j] (1 ≤ i ≤ j ≤ |s|) of string s is string sisi + 1...sj.
- The prefix of string s of length l (1 ≤ l ≤ |s|) is string s[1..l].
- The suffix of string s of length l (1 ≤ l ≤ |s|) is string s[|s| - l + 1..|s|].
Your task is, for any prefix of string s which matches a suffix of string s, print the number of times it occurs in string s as a substring.
The single line contains a sequence of characters s1s2...s|s| (1 ≤ |s| ≤ 105) — string s. The string only consists of uppercase English letters.
In the first line, print integer k (0 ≤ k ≤ |s|) — the number of prefixes that match a suffix of string s. Next print k lines, in each line print two integers li ci. Numbers li ci mean that the prefix of the length li matches the suffix of length li and occurs in string s as a substring ci times. Print pairs li ci in the order of increasing li.
ABACABA
3
1 4
3 2
7 1
AAA
3
1 3
2 2
3 1
题意:
给出一个字符串,问每种既是前缀,又是后缀的字符串出现的次数kmp+dp,利用kmp求出所有的前后缀,考虑到若第i位既是前缀又是后缀,则kmp中的p[i]位也一定是,由此可以得到一个状态转移的方程dp[p[i]]+=dp[i],初始化所有的dp[i]=1,因为还包括它本身。
我队友curs0r是用后缀数组做的。。。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <sstream> 3 #include <ios> 4 #include <iomanip> 5 #include <functional> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <list> 10 #include <queue> 11 #include <deque> 12 #include <stack> 13 #include <set> 14 #include <map> 15 #include <cstdio> 16 #include <cstdlib> 17 #include <cmath> 18 #include <cstring> 19 #include <climits> 20 #include <cctype> 21 using namespace std; 22 #define XINF INT_MAX 23 #define INF 0x3FFFFFFF 24 #define MP(X,Y) make_pair(X,Y) 25 #define PB(X) push_back(X) 26 #define REP(X,N) for(int X=0;X<N;X++) 27 #define REP2(X,L,R) for(int X=L;X<=R;X++) 28 #define DEP(X,R,L) for(int X=R;X>=L;X--) 29 #define CLR(A,X) memset(A,X,sizeof(A)) 30 #define IT iterator 31 typedef long long ll; 32 typedef pair<int,int> PII; 33 typedef vector<PII> VII; 34 typedef vector<int> VI; 35 #define MAXN 100010 36 char s[MAXN]; 37 int p[MAXN]; 38 int dp[MAXN]; 39 int vis[MAXN]; 40 void getp() 41 { 42 p[1]=0; 43 int len=strlen(s+1); 44 for(int i=2,j=0;i<=len;i++) 45 { 46 while(j>0&&s[j+1]!=s[i])j=p[j]; 47 if(s[j+1]==s[i])j+=1; 48 p[i]=j; 49 } 50 } 51 52 53 int main() 54 { 55 ios::sync_with_stdio(false); 56 while(cin>>s+1) 57 { 58 int len=strlen(s+1); 59 getp(); 60 for(int i=1;i<=len;i++) 61 { 62 dp[i]=1; 63 } 64 int i=len; 65 int k=0; 66 while(i) 67 { 68 vis[k]=i; 69 k++; 70 i=p[i]; 71 } 72 for(i=len;i>0;i--) 73 { 74 dp[p[i]]+=dp[i]; 75 } 76 cout<<k<<endl; 77 for(i=k-1;i>=0;i--) 78 { 79 cout<<vis[i]<<" "<<dp[vis[i]]<<endl; 80 } 81 } 82 return 0; 83 }