zoukankan      html  css  js  c++  java
  • SPOJ

    题意

    给定字符串,(q) 次询问,每次查询字典序第 (k) 小的子串。

    思路

    后缀自动机模版题。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    const int maxm = maxn << 1;
    
    struct SAM {
        int link[maxm], cnt[maxm], len[maxm];
        int nxt[maxm][26];
        int last, tot;
    
        void init() {
            len[0] = link[0] = 0;
            last = tot = 1;
        }
    
        void extend(int c) {
            c -= 'a';
            int cur = ++tot, p = last;
            len[cur] = len[last] + 1;
    //        cnt[cur] = 1;
            for (; p && !nxt[p][c]; p = link[p]) nxt[p][c] = cur;
            if (!p) {
                link[cur] = 1;
            } else {
                int q = nxt[p][c];
                if (len[q] == len[p] + 1) {
                    link[cur] = q;
                } else {
                    int clone = ++tot;
                    len[clone] = len[p] + 1;
                    memcpy(nxt[clone], nxt[q], sizeof(nxt[q]));
                    link[clone] = link[q];
                    for (; p && nxt[p][c] == q; p = link[p]) nxt[p][c] = clone;
                    link[q] = link[cur] = clone;
                }
            }
            last = cur;
        }
    
        void dfs(int x) {
            cnt[x] = 1;
            for (int i = 0; i < 26; ++i) {
                if(!nxt[x][i]) continue;
                if(!cnt[nxt[x][i]]) dfs(nxt[x][i]);
                cnt[x] += cnt[nxt[x][i]];
            }
        }
    
        void query(int x, int k) {
            if (!k) return puts(""), void();
            for (int i = 0; i < 26; ++i) {
                if (!nxt[x][i]) continue;
                if (k <= cnt[nxt[x][i]]) {
                    putchar(i + 'a');
                    query(nxt[x][i], k - 1);
                    break;
                } else {
                    k -= cnt[nxt[x][i]];
                }
            }
        }
    
    } sam;
    
    char str[maxn];
    int q, x;
    
    int main() {
    //    freopen("input.in", "r", stdin);
        sam.init();
        scanf("%s", str);
        for (int i = 0; str[i]; ++i) sam.extend(str[i]);
        sam.dfs(1);
        scanf("%d", &q);
        while (q--) {
            scanf("%d", &x);
            sam.query(1, x);
        }
        return 0;
    }
    
  • 相关阅读:
    怎样查看Oracle的数据库名称sid
    request.getRemoteAddr request.getRemoteHost()
    Oracle中添加自动编号的序列
    google chrome 快捷键
    MyEclipse快捷键大全( 再排版)
    Java正则表达式应用详解
    Spring3.1 Cache注解
    Java本周总结1.
    jquery ui 自动补全
    用字符串的length实现限制文本框长度
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11705215.html
Copyright © 2011-2022 走看看