codeforces432D Prefixes and Suffixes(kmp+dp)

转载请注明出处: 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 }
代码君

 

你可能感兴趣的:(codeforces)