对于字符串 S ,有一个指针 i ,如果存在从 j ( j<i )开始的子串是 suf(i) 的前缀,且其长度为 k 最大,那么输出 k 以及 j (如果 j 不唯一输出最小的),如果不存在 j ,那么i++
,输出-1以及该字符的ascii值。
子串肯定从自动机初始状态开始找,由于子串必须在j之前存在,因此我们需要在线构造自动机。即i指针移动的时候更新自动机。
然后子串的话直接匹配就好。
如果匹配到了,输出匹配长度,以及子串开头,也就是我们当前走到的状态的Right集合的最小值再减去其长度。
匹配不到就匹配不到咯。。
Rank 2惊了。
没想到有啥可以变成Rank 1的方法?
#include <cstdio>
#include <cstring>
const int rt = 1, N = 200005;
int last = 1, cnt = 1;
int ch[N][26], fa[N], rr[N], ma[N];
char str[N];
void add(char c) {
int np = ++cnt, p = last; last = np; rl[np] = ma[np] = ma[p] + 1;
memset(ch[np], 0, sizeof ch[np]);
while (p && !ch[p][c]) ch[p][c] = np, p = fa[p];
if (!p) fa[np] = rt;
else {
int q = ch[p][c];
if (ma[p] + 1 == ma[q]) fa[np] = q;
else {
int nq = ++cnt; ma[nq] = ma[p] + 1; rl[nq] = rl[q];
memcpy(ch[nq], ch[q], sizeof ch[q]);
fa[nq] = fa[q]; fa[q] = fa[np] = nq;
while (p && ch[p][c] == q) ch[p][c] = nq, p = fa[p];
}
}
}
int main() {
int t, kase = 0, l, i, p;
scanf("%d", &t);
while (t--) {
last = cnt = rt;
memset(ch[rt], 0, sizeof ch[rt]);
scanf("%s", str);
printf("Case #%d:\n", ++kase);
for (i = 0; str[i]; ) {
for (p = rt, l = 0; str[i] && ch[p][str[i] - 'a']; ++l, ++i) {
p = ch[p][str[i] - 'a'];
add(str[i] - 'a', i);
}
if (l) printf("%d %d\n", l, rl[p] - l);
else add(str[i] - 'a', i), printf("-1 %d\n", str[i++]);
}
}
return 0;
}
Alice wants to send a classified message to Bob. She tries to encrypt the message with her original encryption method. The message is a string S, which consists of N lowercase letters.
S[a…b] means a substring of S ranging from S[a] to S[b] (0≤a≤b
The first line of input contains an integer T, which represents the number of test cases (T≤50). Each test case contains a line of string, which has no more than 100000 lowercase letters. It is guaranteed that the total length of the strings is not greater than 2×106.
For each test case, output a single line consisting of “Case #X:” first. X is the test case number starting from 1. Output the ciphertext in the following lines. Each line contains two integers separated by a single space.
2
aaaaaa
aaaaabbbbbaaabbc
Case #1:
-1 97
5 0
Case #2:
-1 97
4 0
-1 98
4 5
5 2
-1 99
2015ACM/ICPC亚洲区合肥站-重现赛(感谢中科大)
wange2014