HDU 5558 Alice's Classified Message 后缀自动机

对于字符串 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’s Classified Message

Problem Description

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

Input

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.

Output

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.

Sample Input

2
aaaaaa
aaaaabbbbbaaabbc

Sample Output

Case #1:
-1 97
5 0
Case #2:
-1 97
4 0
-1 98
4 5
5 2
-1 99

Source

2015ACM/ICPC亚洲区合肥站-重现赛(感谢中科大)

Recommend

wange2014

你可能感兴趣的:(字符串,HDU,后缀自动机,OI)