bzoj4477 4477: [Jsoi2015]字符串树 可持久化字典树
pass
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int MAXN = 1100000; 7 int cnt,n,tot,q; 8 int ch[MAXN][26],head[MAXN],rt[MAXN],dep[MAXN],siz[MAXN],to[MAXN],nxt[MAXN]; 9 int p[MAXN][30]; 10 char str[MAXN][15]; 11 void add(int x,int y,char *s) 12 { 13 nxt[++cnt] = head[x]; 14 to[cnt] = y; 15 head[x] = cnt; 16 memcpy(str[cnt],s,sizeof(str[cnt])); 17 } 18 void dfs(int x,int frm) 19 { 20 for (int i = head[x];i;i = nxt[i]) 21 { 22 if (to[i] == frm) 23 continue; 24 p[to[i]][0] = x; 25 dep[to[i]] = dep[x] + 1; 26 int u = rt[x],v = rt[to[i]] = ++tot,lenn = strlen(str[i] + 1); 27 for (int j = 1;j <= lenn;j++) 28 { 29 for (int o = 0;o <= 25;o++) 30 { 31 siz[v] += siz[ch[u][o]]; 32 ch[v][o] = ch[u][o]; 33 } 34 siz[v]++; 35 u = ch[u][str[i][j] - 'a']; 36 ch[v][str[i][j] - 'a'] = ++tot; 37 v = tot; 38 } 39 siz[v]++; 40 dfs(to[i],x); 41 } 42 } 43 int lca(int x,int y) 44 { 45 int t = log2(n); 46 if (dep[x] < dep[y]) 47 swap(x,y); 48 for (int i = t;i >= 0;i--) 49 if (dep[x] - (1 << i) >= dep[y]) 50 x = p[x][i]; 51 if (x == y) 52 return x; 53 for (int i = t;i >= 0;i--) 54 if (p[x][i] != p[y][i]) 55 { 56 x = p[x][i]; 57 y = p[y][i]; 58 } 59 return p[x][0]; 60 } 61 int lca_init() 62 { 63 int t = log2(n); 64 for (int i = 1;i <= t;i++) 65 for (int j = 1;j <= n;j++) 66 p[j][i] = p[p[j][i - 1]][i - 1]; 67 } 68 int solve(int x,char *s) 69 { 70 int u = rt[x],lenn = strlen(s + 1); 71 for (int i = 1;i <= lenn;i++) 72 u = ch[u][s[i] - 'a']; 73 return siz[u]; 74 } 75 int main() 76 { 77 scanf("%d",&n); 78 int tu,tv; 79 char ts[15]; 80 for (int i = 1;i <= n - 1;i++) 81 { 82 scanf("%d%d%s",&tu,&tv,ts + 1); 83 add(tu,tv,ts); 84 add(tv,tu,ts); 85 } 86 dep[1] = 1; 87 dfs(1,0); 88 lca_init(); 89 scanf("%d",&q); 90 for (int i = 1;i <= q;i++) 91 { 92 scanf("%d%d%s",&tu,&tv,ts + 1); 93 int t = lca(tu,tv); 94 printf("%d\n",solve(tu,ts) + solve(tv,ts) - 2 * solve(t,ts)); 95 } 96 }
心之所动 且就随缘去吧