CSU-ACM2017暑期训练12-KMP G
来源:互联网 发布:网络用语dp什么意思 编辑:程序博客网 时间:2024/06/12 01:46
G - Next[]树 CodeForces - 432D
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.
Example
InputABACABAOutput31 43 27 1InputAAAOutput31 32 23 1
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <queue>using namespace std;const int maxn = 1e5+10;char s[maxn];int Next[maxn], saveLen[maxn], occurrence[maxn], num[maxn];void getNext(){ int len = strlen(s); int j; Next[0] = Next[1] = 0; for(int i = 1; i < len; i++){ j = Next[i]; while(j && s[i] != s[j]) j = Next[j]; if(s[i] == s[j]) Next[i + 1] = j + 1; else Next[i + 1] = 0; }}int main(){#ifdef TESTfreopen("test.txt", "r", stdin);#endif // TEST while(scanf("%s", s) != EOF){ getNext(); int cnt = 0, len = strlen(s); for(int i = 0; i <= len; i++) occurrence[i] = 1; for(int i = len; i >= 1; i--) occurrence[Next[i]] += occurrence[i]; int temp = len; while(temp){ num[cnt] = occurrence[temp]; saveLen[cnt] = temp; cnt++; temp = Next[temp]; } cout << cnt << endl; for(int i = cnt - 1; i >= 0; i--) cout << saveLen[i] << " " << num[i] << endl; } return 0;}
阅读全文
0 0
- CSU-ACM2017暑期训练12-KMP G
- CSU-ACM2017暑期训练12-KMP D
- CSU-ACM2017暑期训练12-KMP E
- CSU-ACM2017暑期训练12-KMP F
- CSU-ACM2017暑期训练12-KMP H
- CSU-ACM2017暑期训练4-dfs G
- CSU-ACM2017暑期训练6-bfs G
- CSU-ACM2017暑期训练3-递推与递归 G
- CSU-ACM2017暑期训练3-递推与递归 G
- CSU-ACM2017暑期训练16-树状数组 G
- CSU-ACM2017暑期训练3 J
- CSU-ACM2017暑期训练4-dfs D
- CSU-ACM2017暑期训练4-dfs E
- CSU-ACM2017暑期训练4-dfs F
- CSU-ACM2017暑期训练5-三分 E
- CSU-ACM2017暑期训练6-bfs C
- CSU-ACM2017暑期训练6-bfs I
- CSU-ACM2017暑期训练6-bfs H
- 设计模式(二)
- Java理论与实践:正确使用volatile变量
- 572. Subtree of Another Tree
- Synchronized的个人学习总结
- 泛型
- CSU-ACM2017暑期训练12-KMP G
- A. Vladik and Courtesy
- 文本挖掘--数据文本处理-java
- SQL Server返回两个Date日期相差共多少天零多少小时零多少分钟零多少秒
- 2-8连接到LDAP
- linux安装fcitx
- 练习 3-6 修改itoa函数,使得该函数可以接收三个参数。其中,第三个参数为最小字段宽度。为了保证转换后所得的结果至少具有第三个参数指定的最小宽度,在必要时应在所得结果的左边填充一定的空格。
- linux源码安装mysql
- Camera app 分析(四)预览与滤镜