字典树问题

对于普通的字典树,可以加一个vector数组记录非空的孩子,加快速度

还可以用左孩子右兄弟来节省空间,因为普通的trie的话是

int next[MAXN][26]

而左孩子右兄弟可以把[26]省掉,这题实际上并不需要这么节省也可以AC

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #define MAXN 4000*1000+10
 7 #define ll long long
 8 using namespace std;
 9 struct Trie{
10     int nxt[MAXN][65];
11     int v[MAXN];
12     vector<int> son[MAXN];
13     int tot;
14     int newnode(){
15         tot++;
16         memset(nxt[tot],0,sizeof(nxt[tot]));
17         v[tot]=0;
18         son[tot].clear();
19         return tot;
20     }
21     void init(){
22         tot=0;
23         newnode();
24     }
25     int ind(char c){
26         if('0'<=c&&c<='9') return c-48;
27         else if('a'<=c&&c<='z') return c-87;
28         else return c-29;
29     }
30     void insert(char s[]){
31         int p=1;
32         int len=strlen(s);
33         for(int i=0;i<len;i++){
34             int t=ind(s[i]);
35             if(nxt[p][t]){
36                 p=nxt[p][t];
37             }
38             else{
39                 nxt[p][t]=newnode();
40                 son[p].push_back(t);
41                 p=nxt[p][t];
42             }
43         }
44         v[p]++;
45     }
46     pair<ll,int> find(int p,int dep){
47         ll ret=1LL*(v[p])*(v[p]-1)*(dep+1);
48         int cnt=0;
49         for(int i=0;i<son[p].size();i++){
50             int tt=son[p][i];
51             if(nxt[p][tt]){
52                 pair<ll,int> t=find(nxt[p][tt],dep+1);
53                 ret+=t.first;
54                 ret+=1LL*cnt*t.second*(2*dep+1);
55                 cnt+=t.second;
56             }
57         }
58         ret+=1LL*cnt*(v[p])*(2*dep+1);
59         cnt+=v[p];
60         return make_pair(ret,cnt);
61     }
62 }D;
63 int n;
64 char s[1005];
65 int main()
66 {
67     int T;
68     while(1){
69         scanf("%d",&n);
70         if(!n)break;
71         D.init();
72         for(int i=1;i<=n;i++){
73             scanf("%s",s);
74             D.insert(s);
75         }    
76         printf("Case %d: %lld\n",++T,D.find(1,0).first);
77     }
78     return 0;
79 }
普通字典树

相关文章: