dfs时在父亲的基础上加一个字符串,即它和父亲的连边所代表字符串。//一定要记得把父亲的信息完整的传递啊。
利用树上差分的思想,u到v最短路上有多少字符串以s为前缀 = 根到u的路径上有多少字符串以s为前缀+根到v的路径上有多少字符串以s为前缀 – 2 * 根到lca(u,v)的路径上有多少字符串以s为前缀
其实是到板子题,把板子背好就好。//注意数组开的大小啊,我sum开小了最开始一直re.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,tp,nex[200005],toh[200005],tov[200005],h[200005];
int dep[200005], fa[200005], top[200005], siz[200005], son[200005], root[200005];
int tr[1000005][27], cnt, sum[27000005];
char s[100005][15], s1[15];
void read(int &x)
{
int f = 0; x = 0; char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = 1; c = getchar();}
while(c >= '0' && c <= '9'){x = x * 10 + c - '0'; c = getchar();}
if(f) x = -x;
}
void add(int x,int y, int i)
{tp++; nex[tp] = h[x]; toh[tp] = i; tov[tp] = y; h[x] = tp;}
int insert(int nd,int x)
{
int len = strlen(s[x]); int nd1 = ++ cnt; int he = nd1;
for(int i = 0; i < len; i++)
{
int ha = s[x][i] - 'a';
for(int j = 0; j <= 25; j++) tr[nd1][j] = tr[nd][j];
tr[nd1][ha] = ++ cnt;
nd1 = tr[nd1][ha];nd = tr[nd][ha];
sum[nd1] += sum[nd]; sum[nd1] += 1;
}
return he;
}
void dfs(int x,int f)
{
fa[x] = f; siz[x] = 1;
for(int i = h[x]; i; i = nex[i])
{
int v = tov[i]; if(v == f) continue;
root[v] = insert(root[x],toh[i]);
dep[v] = dep[x] + 1; dfs(v,x); siz[x] += siz[v];
if(siz[v] > siz[son[x]]) son[x] = v;
}
}
void dfs1(int x,int f)
{
top[x] = f; if(son[x]) dfs1(son[x],f);
for(int i = h[x]; i; i = nex[i])
{
int v = tov[i]; if(v == fa[x] || v == son[x]) continue;
dfs1(v,v);
}
}
int lca(int x,int u)
{
while(top[x] != top[u])
{
if(dep[top[u]] > dep[top[x]] ) swap(x,u); x = fa[top[x]];
}
return dep[x] > dep[u] ? u : x;
}
int qurey(int x,char ss[15])
{
int nd = x;
for(int i = 0; i < strlen(ss); i++)
{int ha = ss[i] - 'a'; nd = tr[nd][ha];}
return sum[nd];
}
int main()
{
read(n);
for(int i = 1; i < n; i++)
{int x,y; read(x); read(y); scanf("%s",s[i]); add(x, y, i); add(y, x, i);}
dfs(1,1);dfs1(1,1);
int q ;read(q);
for(int i = 1; i <= q; i++)
{
int x,y; read(x); read(y); scanf("%s",s1);
int l = lca(x,y);
int ans1 = qurey(root[x],s1);
int ans2 = qurey(root[y],s1);
int ans3 = qurey(root[l],s1);
printf("%d\n",ans1 + ans2 - 2 * ans3);
}
return 0;
}