Uva11732(trie)

题意:给你n个字符串 用strcmp()两两比较 ,求字符比较的总次数

分析:

数据量很大我们考虑用孩子兄弟表示法来表示字典树

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 0;
const int MAXNODE =    4000010;
int n, cas;
ll ans;
char str[4001];

struct Trie {
    int son[MAXNODE];
    int bro[MAXNODE];
    int val[MAXNODE];
    char ch[MAXNODE];
    int num;
    void init() { num = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
        //孩子兄弟表示法
    void build(char *s) {
        int len = strlen(s), u = 0, v;
        for(int i=0;i<=len;++i){
            for (v = son[u]; v; v = bro[v]) {
                if (ch[v] == s[i])
                    break;
            }
            if (!v) {
                v = num++;
                ch[v] = s[i];
                bro[v] = son[u];
                son[v] = 0;
                val[v] = 0;
                son[u] = v;
            }
            ans += (val[u] - val[v]) * (2 * i + 1);//每插入一个串累加比较次数
            if (len == i) {
                ans += val[v] * (2 * i + 2);
                val[v]++;
            }
            val[u]++;
            u = v;
        }
    }
} trie;
int main() {
    while (~scanf("%d", &n) && n) {
        trie.init();
        ans = 0;
        for (int i=0;i<n;++i) {
            scanf("%s", str);
            trie.build(str);
        }
        printf("Case %d: %lld\n", ++cas, ans);
    }
    return 0;
}    

 

posted on 2015-08-09 17:32  积跬步、至千里  阅读(161)  评论(0编辑  收藏  举报

导航