题目链接:http://hihocoder.com/problemset/problem/1107
题意:求有多少非依赖前缀,使得前缀下标识的字符串不超过5个。
这里非依赖的意思是,假如前缀a,b,a是b的前缀,则b依赖于a。假如a下标识的字符串已经不超过5个了,那么b就不能统计了。
trie树直接搞,遇到<=5的前缀就计数,否则递归一层。
写了一种非指针的trie树,val存值,id存某一层某一个节点的下一个节点的id。sz维护接下来要插入的id。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 10100; 5 const int maxm = 2001000; 6 const int maxc = 30; 7 typedef struct Trie { 8 int root, sz; 9 int val[maxm], id[maxm][maxc]; 10 void build() { 11 root = 0; sz = 0; 12 memset(val, 0, sizeof(val)); 13 memset(id, -1, sizeof(id)); 14 val[root] = 0x7f7f7f7; 15 } 16 void insert(const char* str) { 17 int len = strlen(str); 18 int u = root; 19 for(int i = 0; str[i]; i++) { 20 int v = str[i] - 'a'; 21 if(id[u][v] == -1) id[u][v] = ++sz; 22 u = id[u][v]; 23 val[u]++; 24 } 25 } 26 int dfs(int u) { 27 if(val[u] <= 5) return 1; 28 int ret = 0; 29 for(int i = 0; i < 26; i++) { 30 if(id[u][i] != -1) { 31 ret += dfs(id[u][i]); 32 } 33 } 34 return ret; 35 } 36 }Trie; 37 38 int n; 39 Trie trie; 40 char tmp[maxm]; 41 42 int main() { 43 // freopen("in", "r", stdin); 44 while(~scanf("%d", &n)) { 45 trie.build(); 46 for(int i = 0; i < n; i++) { 47 scanf("%s", tmp); 48 trie.insert(tmp); 49 } 50 printf("%d ", trie.dfs(trie.root)); 51 } 52 return 0; 53 }