码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces432D Prefixes and Suffixes(kmp+dp)

时间:2015-03-14 22:58:37      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

 

D. Prefixes and Suffixes

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.

Input

The single line contains a sequence of characters s1s2...s|s| (1 ≤ |s| ≤ 105) — string s. The string only consists of uppercase English letters.

Output

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.

Sample test(s)
Input
ABACABA
Output
3
1 4
3 2
7 1
Input
AAA
Output
3
1 3
2 2
3 1

题意:

  给出一个字符串,问每种既是前缀,又是后缀的字符串出现的次数kmp+dp,利用kmp求出所有的前后缀,考虑到若第i位既是前缀又是后缀,则kmp中的p[i]位也一定是,由此可以得到一个状态转移的方程dp[p[i]]+=dp[i],初始化所有的dp[i]=1,因为还包括它本身。

我队友curs0r是用后缀数组做的。。。。。。

技术分享
 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 }
代码君

 

codeforces432D Prefixes and Suffixes(kmp+dp)

标签:

原文地址:http://www.cnblogs.com/fraud/p/4338453.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!