造一个广义后缀自动机,LCT维护即可,询问1可以在插入的时候直接维护
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iomanip> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<bitset> using namespace std; #define MAXN 200010 #define MAXM 1010 #define ll long long #define INF 1000000000 #define MOD 1000000007 #define eps 1e-8 struct vec{ int to; int fro; int v; }; struct LCT{ int fa[MAXN],son[MAXN][2],sum[MAXN],ch[MAXN]; int st[MAXN],tp; inline bool ir(int x){ return son[fa[x]][0]!=x&&son[fa[x]][1]!=x; } inline void cot(int x,int y,int z){ if(x){ fa[x]=y; } if(y){ son[y][z]=x; } } inline void rot(int x,bool z){ int xx=fa[x],xxx=fa[xx]; cot(son[x][z],xx,z^1); if(!ir(xx)){ cot(x,xxx,son[xxx][1]==xx); }else{ fa[x]=xxx; } cot(xx,x,z); } inline void toch(int x,int y){ if(!x){ return ; } sum[x]+=y; ch[x]+=y; } inline void pd(int x){ toch(son[x][0],ch[x]); toch(son[x][1],ch[x]); ch[x]=0; } void splay(int x){ st[++tp]=x; for(int i=x;!ir(i);i=fa[i]){ st[++tp]=fa[i]; } for(;tp;tp--){ pd(st[tp]); } int xx=fa[x],xxx=fa[xx]; while(!ir(x)){ if(ir(xx)){ rot(x,son[xx][0]==x); }else{ bool z=son[xxx][0]==xx; if(son[xx][z]==x){ rot(x,z^1); rot(x,z); }else{ rot(xx,z); rot(x,z); } } xx=fa[x]; xxx=fa[xx]; } } void acs(int x){ int t=0; while(x){ splay(x); son[x][1]=t; t=x; x=fa[x]; } } void cut(int x){ acs(x); splay(x); fa[son[x][0]]=0; son[x][0]=0; } void link(int x,int y){ cut(x); fa[x]=y; } int ask(int x){ acs(x); splay(x); return sum[x]; } }; LCT T; vec mp[MAXN*2]; int tai[MAXN],cnt; int n,m; char s[MAXN]; int mx[MAXN*2],fa[MAXN*2],son[MAXN*2][3]; int lst[MAXN],tot,rt; bool vis[MAXN]; ll ans; inline void be(int x,int y,int z){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; mp[cnt].v=z; } inline void bde(int x,int y,int z){ be(x,y,z); be(y,x,z); } int ins(int x,int lst){ int p=lst,np=++tot; mx[np]=mx[p]+1; while(p&&(!son[p][x])){ son[p][x]=np; p=fa[p]; } if(!p){ fa[np]=rt; T.link(np,rt); ans+=mx[np]-mx[fa[np]]; }else{ int q=son[p][x]; if(mx[q]==mx[p]+1){ fa[np]=q; T.link(np,q); ans+=mx[np]-mx[fa[np]]; }else{ int nq=++tot; mx[nq]=mx[p]+1; memcpy(son[nq],son[q],sizeof(son[q])); T.link(nq,fa[q]); fa[nq]=fa[q]; ans+=mx[nq]-mx[fa[nq]]; ans-=mx[q]-mx[fa[q]]; T.link(q,nq); fa[q]=nq; ans+=mx[q]-mx[fa[q]]; T.link(np,nq); fa[np]=nq; ans+=mx[np]-mx[fa[np]]; T.acs(nq); T.splay(nq); T.sum[nq]=T.sum[q]; while(p&&son[p][x]==q){ son[p][x]=nq; p=fa[p]; } } } T.acs(np); T.splay(np); T.toch(np,1); return np; } void dfs(int x){ int i,y; vis[x]=1; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(!vis[y]){ lst[y]=ins(mp[i].v,lst[x]); dfs(y); } } } char z[MAXN]; int main(){ lst[1]=rt=tot=1; int i,o,x,y; scanf("%*d%d",&n); for(i=1;i<n;i++){ scanf("%d%d%s",&x,&y,z); bde(x,y,z[0]-'a'); } dfs(1); scanf("%d",&m); while(m--){ scanf("%d",&o); if(o==1){ printf("%lld\n",ans); }else if(o==2){ scanf("%d%d",&o,&n); for(i=1;i<n;i++){ scanf("%d%d%s",&x,&y,z); bde(x,y,z[0]-'a'); } dfs(o); }else{ scanf("%s",z+1); int p=rt; int len=strlen(z+1); bool flag=1; for(i=1;i<=len;i++){ if(!son[p][z[i]-'a']){ flag=0; break; } p=son[p][z[i]-'a']; } if(!flag){ printf("0\n"); }else{ printf("%d\n",T.ask(p)); } } } return 0; } /* 1 4 1 2 a 1 3 b 2 4 b 6 1 2 2 4 2 5 b 2 6 c 5 7 b 1 3 ab 2 6 3 6 8 a 6 9 b 1 */