zoukankan      html  css  js  c++  java
  • UVA 11732 链表+字典树

    因为字符集比较大,所以就不能用简单字典树,在字典树里面,用链表进行存储。这个倒是不难,练了下手

    统计的时候还是有点难搞,因为要算所有的两两比较的次数之和,对分叉处进行计算,注意细节

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N = 4000*1000+10;
    struct Trie
    {
        int head[N];
        int next[N];
        char ch[N];
        int tot[N];
        int sz;
        long long ans;
        void clear()
        {
            sz=1;
            head[0]=next[0]=tot[0]=0;
            ans=0;
        }
        void insert(const char* s)
        {
            int u=0,v,len;
            len=strlen(s);
            tot[0]++;
            for (int i=0; i<=len; i++)
            {
                bool found=false;
                for (v=head[u]; v!=0; v=next[v])
                {
                    if (ch[v]==s[i])
                    {
                        found=true;
                        break;
                    }
                }
                if (!found)
                {
                    v=sz++;
                    ch[v]=s[i];
                    tot[v]=0;
                    next[v]=head[u];
                    head[u]=v;
                    head[v]=0;
                }
                u=v;
                tot[u]++;
            }
        }
    
        void dfs(int depth, int u) //计算总数
        {
            if(head[u] == 0)
                ans += tot[u] * (tot[u] - 1) * depth;
            else
            {
                int sum = 0;
                for(int v = head[u]; v != 0; v = next[v])
                    sum += tot[v] * (tot[u] - tot[v]);
                ans += sum / 2 * (2 * depth + 1);
                for(int v = head[u]; v != 0; v = next[v])
                    dfs(depth+1, v);
            }
        }
    
        long long count()
        {
            ans = 0;
            dfs(0, 0);
            return ans;
        }
    } T;
    char str[1010];
    int main()
    {
        int n;
    
        int kase=0;
        while (scanf("%d",&n) && n)
        {
            T.clear();
            for (int i=1; i<=n; i++)
            {
                scanf("%s",str);
                T.insert(str);
            }
            T.count();
            printf("Case %d: %lld
    ",++kase,T.ans);
        }
        return 0;
    }
  • 相关阅读:
    高可用Redis服务架构分析与搭建
    Java 程序性能问题
    限流、熔断、服务降级理解
    设计模式-享元设计
    设计模式-原型设计
    java8 Stream原理
    SQL语句性能优化策略
    OAuth2和JWT
    5种常见的Docker Compose错误
    leetcode_699. 掉落的方块
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3668777.html
Copyright © 2011-2022 走看看