Page 1 of 212

Codechef April Challenge 2012. Substrings on a Tree

Brief description:

給定一個 tire,求其中互不相同的子串的個數。之後每次詢問,求將 a-z 的優先順序重拍後字典序第 kth 大的子串。

Analysis:

廣義後綴自動機。注意這個是 12 年的題。。。

修改 Ext() 過程,tail 指針現在需要作為參數傳入。。。

    int Ext(int c, int tail){
        int u = tail, uu = new_node(); len[uu] = len[u] + 1;
        while (u && !v) v = uu, u = p;
        if (!u && !v) v = uu, pp = 0;
        else{
            if (len[v] == len[u] + 1) pp = v;
            else{
                int _v = v, vv = new_node(_v); len[vv] = len[u] + 1;
                par[_v] = pp = vv; while (v == _v) v = vv, u = p;
            }
        }
        return uu;
    }

之後。。

    void Init(){

        RD(n, q); RS(s+1); n = strlen(s+1); REP_1(i, n) s[i] -= 'a';

        //RST(hd);
        FOR_C(i, 2, n<<1){
            RD(aa, bb);
            suc[i] = hd[aa], hd[aa] = i++;
            suc[i] = hd[aa], hd[aa] = i;
        }

        tot = 0; queue<int> Q; Q.push(1);
        GtoM[1] = Ext(s[1], new_node());

        while(SZ(Q)){
            int u = Q.front(); Q.pop();
            REP_G(i, u) if (!GtoM[v]){
                GtoM[v] = Ext(s[v], GtoM[u]);
                Q.push(v);
            }
        }
    }

Select 的過程參照 SPOJ SUBLEX 即可。

http://www.codechef.com/viewsolution/4511141

Page 1 of 212