zoukankan      html  css  js  c++  java
  • BZOJ 4567: [Scoi2016]背单词

    二次联通门 : BZOJ 4567: [Scoi2016]背单词

    /*
        BZOJ 4567: [Scoi2016]背单词
    
        Trie + 贪心
    
        大家都吐槽题目反人类
        可我觉得还好,毕竟见的多了
        
        不会做啊。。
        正解好巧妙
        
        考虑一下,发现一操作完全不必要,可以省去
        因为所有的字符串的后缀关系会形成一个树
    
        那么把字符串倒序插入Trie中
        建树,每次向子树小的一个点转移即可
    */
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define Max 100008
    #define L 26
    int N;
    char line[Max];
    
    int trie[Max][L], T_C = 1;
    bool is[Max];
    struct E
    {
        E *n; int to;
    };
    E *list[Max], poor[Max], *Ta = poor;
    void Dfs (int now, int Father)
    {
        if (is[now]) 
        {
            ++ Ta, Ta->to = now, Ta->n = list[Father], list[Father] = Ta;
            Father = now;
        }
        for (int i = 0; i < L; ++ i) 
            if (trie[now][i]) 
                Dfs (trie[now][i], Father);
    }
    int size[Max];
    
    void Re_Dfs (int now)
    {
        size[now] = 1;
        for (E *e = list[now]; e; e = e->n)
            Re_Dfs (e->to), size[now] += size[e->to];
    }
    int dfn[Max], top, C, Stack[Max], Answer;
    inline bool Comp (int a, int b)
    {
        return size[a] < size[b];
    }
    void Get_Answer (int now)
    {
        dfn[now] = ++ C; int pos = top + 1;
        for (E *e = list[now]; e; e = e->n)
            Stack[++ top] = e->to;
        if (top < pos) return ;
        std :: sort (Stack + pos, Stack + top + 1, Comp);
        for (int i = pos; i <= top; ++ i)
            Get_Answer (Stack[i]), Answer += dfn[Stack[i]] - dfn[now];
        top = pos - 1;
    }
    
    int Main ()
    {
        scanf ("%d", &N); register int i, j;
        int Id, x, now, Len;
        for (i = 1; i <= N; ++ i)
        {
            scanf ("%s", line); Len = strlen (line);
            for (j = Len - 1, now = 1; j >= 0; -- j)
            {
                Id = line[j] - 'a';
                if (trie[now][Id] == 0)
                    trie[now][Id] = ++ T_C;
                now = trie[now][Id];
            }    
            is[now] = true;
        }    
        Dfs (1, 1), Re_Dfs (1), Get_Answer (1);
        printf ("%d", Answer);
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {;}
  • 相关阅读:
    IntelliJ IDEA创建Java项目
    Oracle常见五个服务的作用
    Windows2008开启telnet客户端命令
    整理jQuery操作select控件常用功能代码
    Asp.Net程序报错
    Oracle中start with connect by prior用法
    Spring中无法访问resources目录下页面或静态资源
    对搜狗输入法的个人评价
    课堂练习寻找水王
    典型用户分析及用户场景分析
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7429388.html
Copyright © 2011-2022 走看看