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

对于字符串 S ,有一个指针i,如果存在从 j (j<i)开始的子串是 suf(i) 的前缀,且其长度为 k 最大,那么输出k以及 j (如果j不唯一输出最小的),如果不存在 j <script type="math/tex" id="MathJax-Element-10">j</script>,那么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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值