• BZOJ_3448_[Usaco2014 Feb]Auto-complete_Trie树


    BZOJ_3448_[Usaco2014 Feb]Auto-complete_Trie

    Description

    Bessie the cow has a new cell phone and enjoys sending text messages, although she keeps making spelling errors since she has trouble typing on such a small screen with her large hooves. Farmer John has agreed to help her by writing an auto-completion app that takes a partial word and suggests how to complete it. The auto-completion app has access to a dictionary of W words, each consisting of lowercase letters in the range a..z, where the total number of letters among all words is at most 1,000,000. The app is given as input a list of N partial words (1 <= N <= 1000), each containing at most 1000 lowercase letters. Along with each partial word i, an integer K_i is also provided, such that the app must find the (K_i)th word in alphabetical order that has partial word i as a prefix. That is, if one ordered all of the valid completions of the ith partial word, the app should output the completion that is (K_i)th in this sequence.

    XYW在和他的男人聊天的时候经常会因为打字速度太慢而被鄙视,于是他想开发一种自动补全软件。开始他有一个包含了w个词的字典(总长度不大于10^6)。接下来他想知道在字典中可以由给定的字符串s加上若干个字母得到的字符串字典序第k大的编号是多少?有n组询问(n<=10^3,s长度<=10^3)

    Input

    * Line 1: Two integers: W and N.

     * Lines 2..W+1: Line i+1: The ith word in the dictionary.

    * Lines W+2..W+N+1: Line W+i+1: A single integer K_i followed by a partial word. 

    Output

     * Lines 1..N: Line i should contain the index within the dictionary (an integer in the range 1..W) of the (K_i)th completion (in alphabetical order) of the ith partial word, or -1 if there are less than K_i completions.

    Sample Input

    10 3
    dab
    ba
    ab
    daa
    aa
    aaa
    aab
    abc
    ac
    dadba
    4 a
    2 da
    4 da

    Sample Output

    3
    1
    -1


    并没有想到排序加二分。。

    直接对所有串建立trie树,维护子树siz,这样我们查询的时候从a开始查然后不断减K即可。

    BZ上面加强了数据,直接这么做会T死。

    考虑优化:对于Trie树上那些非叶子节点且只有一个儿子的点,可以直接合并到下面的结点上去。。

    这个玩意是我受到后缀树的启发bb出来的,复杂度也不会证,应该可以卡掉。

    BZ的数据字符总数可能超过1000000。开2100000就够了(我这个做法是这样

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 2100050
    int t[N],ch[N][26],W,n,cnt=1,flg[N],fa[N],is[N],vis[N];
    char w[N];
    void insert(int idx) {
        int p=1,i;  
        for(i=1;w[i];i++) {
            int &k=ch[p][w[i]-'a'];
            if(!k) k=++cnt;
            p=k;
            t[p]++; 
            if(!flg[p]&&!vis[p]) flg[p]=idx;
            else if(!is[p]) flg[p]=0,vis[p]=1;
        }
        is[p]=1;
        flg[p]=idx;
    }
    int query(int p,int k) {
        if(k==1&&flg[p]) return flg[p];
        int i;
        int now=is[p];
        for(i=0;i<26;i++) {
            now+=t[ch[p][i]];
            if(now>=k) {
                return query(ch[p][i],k-now+t[ch[p][i]]);
            }
        }
        return flg[p];
    }
    int main() {
        scanf("%d%d",&W,&n);
        int i,j,sum=0;
        for(i=1;i<=W;i++) {
            scanf("%s",w+1);
            insert(i);
            // sum+=strlen(w+1);
        }
        // printf("%d
    ",sum); return 0;
        int K;
        for(i=1;i<=n;i++) {
            scanf("%d%s",&K,w+1);
            int p=1,flg=1;
            for(j=1;w[j];j++) {
                if(!ch[p][w[j]-'a']) {flg=0; break;}
                p=ch[p][w[j]-'a'];
            }
            if(!flg||t[p]<K) puts("-1");
            else printf("%d
    ",query(p,K)); 
        }
    }
    
  • 相关阅读:
    Alpha 冲刺 (1/10)
    软工实践 · 第七次作业
    福大软工 · 第八次作业(课堂实战)- 项目UML设计(团队)
    软工实践· 第六次作业
    软工实践作业五-结对作业二
    软工实践第四次作业
    软工实践第三次作业
    软工实践第二次作业
    SDN第一次上机作业
    SDN第一次作业——关于网络编程
  • 原文地址:https://www.cnblogs.com/suika/p/9147717.html
Copyright © 2020-2023  润新知