Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define gc c=getchar()
- #define r(x) read(x)
- #define ll long long
- template<typename T>
- inline void read(T&x){
- x=0;T k=1;char gc;
- while(!isdigit(c)){if(c=='-')k=-1;gc;}
- while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
- }
- const int N=100005;
- int n;
- inline char GetChar(){
- char gc;
- while(c<'a'||c>'z')gc;
- return c;
- }
- int ecnt;
- int fir[N];
- int nex[N<<1];
- int to[N<<1];
- char w[N<<1];
- inline void addedge(int u,int v,char c){
- nex[++ecnt]=fir[u],fir[u]=ecnt,to[ecnt]=v,w[ecnt]=c;
- nex[++ecnt]=fir[v],fir[v]=ecnt,to[ecnt]=u,w[ecnt]=c;
- }
- int state;
- int len[N<<1];
- int trans[N<<1][26];
- int slink[N<<1];
- int root[N<<1];
- inline int NewNode(int mx,int *tr,int su){
- ++state;
- len[state]=mx;
- if(tr!=NULL)memcpy(trans[state],tr,26<<2);
- slink[state]=su;
- return state;
- }
- inline int extend(int u,int c){
- int t=NewNode(len[u]+1,NULL,0);
- while(u&&!trans[u][c])trans[u][c]=t,u=slink[u];
- if(!u){
- slink[t]=1;
- return t;
- }
- int v=trans[u][c];
- if(len[v]==len[u]+1){
- slink[t]=v;
- return t;
- }
- int x=NewNode(len[u]+1,trans[v],slink[v]);
- slink[t]=slink[v]=x;
- while(u&&trans[u][c]==v)trans[u][c]=x,u=slink[u];
- return t;
- }
- int fa[N];
- int siz[N];
- int son[N];
- int dep[N];
- char ch[N];
- void dfs1(int x,int f){
- fa[x]=f;
- siz[x]=1;
- dep[x]=dep[f]+1;
- for(int i=fir[x];i;i=nex[i]){
- int v=to[i];
- if(v==f)continue;
- ch[v]=w[i];
- dfs1(v,x);
- siz[x]+=siz[v];
- if(siz[son[x]]<siz[v])son[x]=v;
- }
- }
- int dfs_clock;
- int dfn[N];
- int top[N];
- int ptn[N];
- void dfs2(int x,int t){
- top[x]=t;
- dfn[x]=++dfs_clock;
- ptn[dfs_clock]=x;
- if(!son[x])return ;
- dfs2(son[x],t);
- for(int i=fir[x];i;i=nex[i]){
- int v=to[i];
- if(v==fa[x]||v==son[x])continue;
- dfs2(v,v);
- }
- }
- int tot;
- int ls[N*50];
- int rs[N*50];
- int sum[N*50];
- void insert(int &rt,int l,int r,int x){
- if(!rt)rt=++tot;
- ++sum[rt];
- if(l==r)return ;
- int mid=(l+r)>>1;
- if(x<=mid)insert(ls[rt],l,mid,x);
- else insert(rs[rt],mid+1,r,x);
- }
- int query(int rt,int l,int r,int x,int y){
- if(!rt)return 0;
- if(x<=l&&r<=y)return sum[rt];
- int mid=(l+r)>>1;
- if(y<=mid)return query(ls[rt],l,mid,x,y);
- if(x>mid)return query(rs[rt],mid+1,r,x,y);
- return query(ls[rt],l,mid,x,y)+query(rs[rt],mid+1,r,x,y);
- }
- void merge(int &x,int y){
- if(!x||!y){
- x|=y;
- return ;
- }
- merge(ls[x],ls[y]);
- merge(rs[x],rs[y]);
- sum[x]+=sum[y];
- }
- void dfs3(int x,int lst){
- int t;
- if(x==1)t=NewNode(0,NULL,0);
- else {
- t=extend(lst,ch[x]-'a');
- insert(root[t],1,n,dfn[x]);
- }
- if(!son[x])return ;
- dfs3(son[x],t);
- for(int i=fir[x];i;i=nex[i]){
- int v=to[i];
- if(v==fa[x]||v==son[x])continue;
- dfs3(v,t);
- }
- }
- inline int LCA(int u,int v){
- while(top[u]!=top[v]){
- if(dep[top[u]]<dep[top[v]])swap(u,v);
- u=fa[top[u]];
- }
- return dep[u]<dep[v]?u:v;
- }
- inline int k_lst(int u,int v,int k){
- if(dep[u]-dep[v]<k)return 0;
- int lst;
- while(top[u]!=top[v]){
- if(dep[u]-dep[v]<k)break;
- lst=top[u],u=fa[top[u]];
- }
- if(dep[u]-dep[v]<k)return ptn[dfn[lst]+k-(dep[u]-dep[v])-1];
- else return ptn[dfn[v]+k];
- }
- int Next[N];
- inline int KMP(char *s,int lenS,char *t,int lenT){
- for(int i=2,j=0;i<=lenT;++i){
- while(j&&t[i]!=t[j+1])j=Next[j];
- if(t[i]==t[j+1])++j;
- Next[i]=j;
- }
- int ret=0;
- for(int i=1,j=0;i<=lenS;++i){
- while(j&&s[i]!=t[j+1])j=Next[j];
- if(s[i]==t[j+1])++j;
- if(j==lenT){
- ++ret;
- j=Next[j];
- }
- }
- return ret;
- }
- struct Query{
- int id,x,y;
- };
- vector<Query>Q[N<<1];
- inline void putquery(int id,int u,int x,int y){
- Q[u].push_back(Query{id,x,y});
- }
- int ans[N];
- char s[N];
- inline void solve(int id,int u,int v,char *str){
- int len=strlen(str+1);
- int lca=LCA(u,v);
- if(dep[u]-dep[lca]>=len){
- int u0=k_lst(u,lca,len);
- int A=1;
- for(int i=len;i>=1;--i)A=trans[A][str[i]-'a'];
- while(top[u]!=top[u0]){
- putquery(id,A,dfn[top[u]],dfn[u]);
- u=fa[top[u]];
- }
- putquery(id,A,dfn[u0],dfn[u]);
- u=fa[u0];
- }
- if(dep[v]-dep[lca]>=len){
- int v0=k_lst(v,lca,len);
- int B=1;
- for(int i=1;i<=len;++i)B=trans[B][str[i]-'a'];
- while(top[v]!=top[v0]){
- putquery(id,B,dfn[top[v]],dfn[v]);
- v=fa[top[v]];
- }
- putquery(id,B,dfn[v0],dfn[v]);
- v=fa[v0];
- }
- int m=dep[u]+dep[v]-2*dep[lca];
- int p=0;
- for(;u!=lca;u=fa[u])s[++p]=ch[u];
- int q=m;
- for(;v!=lca;v=fa[v])s[q--]=ch[v];
- ans[id]=KMP(s,m,str,len);
- return ;
- }
- vector<int>G[N<<1];
- void dfs4(int x){
- for(int i=0;i<G[x].size();++i){
- dfs4(G[x][i]);
- merge(root[x],root[G[x][i]]);
- }
- for(int i=0;i<Q[x].size();++i){
- ans[Q[x][i].id]+=query(root[x],1,n,Q[x][i].x,Q[x][i].y);
- }
- }
- int cnt[N];
- int ord[N<<1];
- char str[5000007];
- int main(){
- freopen("starry.in","r",stdin);
- freopen("starry.out","w",stdout);
- r(n);
- for(int i=1;i<n;++i){
- int u,v;r(u),r(v);
- char c=GetChar();
- addedge(u,v,c);
- }
- dfs1(1,0);
- dfs2(1,1);
- dfs3(1,0);
- int q;r(q);
- for(int i=1;i<=q;++i){
- int u,v;r(u),r(v);
- scanf("%s",str+1);
- solve(i,u,v,str);
- }
- /*
- for(int i=1;i<=state;++i)cnt[len[i]]++;
- for(int i=1;i<=n;++i)cnt[i]+=cnt[i-1];
- for(int i=state;i>=1;--i)ord[cnt[len[i]]--]=i;
- for(int i=state;i>=1;--i){
- int u=ord[i];
- for(int j=0;j<Q[u].size();++j){
- Query &x=Q[u][j];
- ans[x.id]+=query(root[u],1,n,x.x,x.y);
- }
- merge(root[slink[u]],root[u]);
- }
- */
- for(int i=2;i<=state;++i){
- G[slink[i]].push_back(i);
- }
- dfs4(1);
- for(int i=1;i<=q;++i)printf("%d\n",ans[i]);
- }
- /*
- 6
- 2 3 g
- 3 4 n
- 5 3 o
- 6 1 n
- 1 2 d
- 7
- 1 6 n
- 6 4 dg
- 6 4 n
- 2 5 og
- 1 2 d
- 6 5 go
- 2 3 g
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement