SPOJ 7258 SUBLEX 后缀自动机

来源:互联网 发布:access数据库好用吗 编辑:程序博客网 时间:2024/06/15 21:41

求第k大子串。

按拓扑序处理出一个点往后有多少条路径到终态。
答案就很明显了。

#include <cstring>#include <cstdio>#define FOR(i,j,k) for(i=j;i<=k;++i)const int rt = 1, N = 500005;int last = 1, cnt = 1, len = 0;int trans[N][26], fa[N], ma[N], v[N], b[N], l[N], bucket[N];char str[N];void add(char c) {    int np = ++cnt, p = last, q, nq; last = np; ma[np] = ++len;    while (p && !trans[p][c]) trans[p][c] = np, p = fa[p];    if (!p) fa[np] = rt;    else {        q = trans[p][c];        if (ma[q] == ma[p] + 1) fa[np] = q;        else {            nq = ++cnt; memcpy(trans[nq], trans[q], sizeof trans[q]);            ma[nq] = ma[p] + 1; fa[nq] = fa[q]; fa[q] = fa[np] = nq;            while (p && trans[p][c] == q) trans[p][c] = nq, p = fa[p];        }    }}void sort(int *x, int *y, int n, int m) {    int i;    FOR(i,1,n) ++bucket[x[i]];    FOR(i,1,m) bucket[i] += bucket[i - 1];    for(i=n;i;--i) y[bucket[x[i]]--] = i;}int main() {    int i, j, n, q, o, k, p;    scanf("%s", str + 1);    n = strlen(str + 1);    FOR(i,1,n) add(str[i] - 'a');    sort(ma, b, cnt, n);    FOR(i,1,cnt) v[i] = 1;    for (i = cnt; i; --i) FOR(j,0,25)        if (trans[b[i]][j]) v[b[i]] += v[trans[b[i]][j]];    for (scanf("%d", &o); o--; putchar('\n')) {        scanf("%d", &k); p = rt;        while (k) FOR(i,0,25) if (trans[p][i]) {            q = trans[p][i];            if (k > v[q]) k -= v[q];            else {                putchar(i + 'a');                p = trans[p][i];                --k;                break;            }        }    }    return 0;}

SUBLEX - Lexicographical Substring Search

Little Daniel loves to play with strings! He always finds different ways to have fun with strings! Knowing that, his friend Kinan decided to test his skills so he gave him a string S and asked him Q questions of the form:

If all distinct substrings of string S were sorted lexicographically, which one will be the K-th smallest?

After knowing the huge number of questions Kinan will ask, Daniel figured out that he can’t do this alone. Daniel, of course, knows your exceptional programming skills, so he asked you to write him a program which given S will answer Kinan’s questions.

Example:

S = “aaa” (without quotes)
substrings of S are “a” , “a” , “a” , “aa” , “aa” , “aaa”. The sorted list of substrings will be:
“a”, “aa”, “aaa”.

Input

In the first line there is Kinan’s string S (with length no more than 90000 characters). It contains only small letters of English alphabet. The second line contains a single integer Q (Q <= 500) , the number of questions Daniel will be asked. In the next Q lines a single integer K is given (0 < K < 2^31).

Output

Output consists of Q lines, the i-th contains a string which is the answer to the i-th asked question.

Example

Input:

aaa
2
2
3

Output:

aa
aaa

0 0
原创粉丝点击