题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2832&mosmsg=Submission+received+with+ID+13213761
P210
注意:字符串的量非常大,用二维的字典树会爆内存
用兄弟节点+儿子节点的字典树以时间换空间
一个节点有子节点和兄弟节点
对于节点u:son[u]为其子节点。
nexts[u] 为u的兄弟节点(相当于一个单链表)
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define ll long long #define maxnode 4000010 ll ans; struct Trie { char ch[maxnode]; int son[maxnode],nexts[maxnode],size; int Have_word[maxnode]; int val[maxnode]; void init(){ size = 1; memset(son, 0, sizeof(son)); memset(nexts, 0, sizeof(nexts)); memset(ch, 0, sizeof(ch)); memset(Have_word, 0, sizeof(Have_word)); memset(val, 0, sizeof(val)); } void insert(char *s){ int u = 0, v, len = strlen(s); for(int i = 0; i <= len; i++) { bool find = false, big = false; for(v = son[u]; v; v = nexts[v]) if(ch[v] == s[i]){ find = true; break; } if(find == false) { v = size++; nexts[v] = son[u]; son[u] = v; ch[v] = s[i]; } ans += (val[u]-val[v])*(i<<1|1); if(i == len) { ans+=val[v]*((i+1)<<1); val[v]++; } val[u]++; u = v; } Have_word[u]++; } }ac; int n; char s[1005]; int main(){ int Cas = 1; while(scanf("%d",&n), n){ ac.init(); ans = 0; while(n--) { scanf("%s",s); ac.insert(s); } printf("Case %d: %lld\n",Cas++,ans); } } /* 2 0 0 3 sadf156A aAS 05sf4s5dfS 3 aZZ AZZ AZZ 3 AZZ AZZ aZZ 4 ABCD ABC ABCD ABD 2 abcd abc */