实在是调不下去了,以后找时间再继续调吧......
Code:
#include <queue> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #define setIO(s) freopen(s".in","r",stdin)// ,freopen(s".out","w",stdout) #define maxn 800000 #define N 2 #define ll long long using namespace std; char str[maxn]; long long cur_ans; struct LCT{ int ch[maxn][2],f[maxn],tag[maxn],sta[maxn],val[maxn]; int get(int x){ return ch[f[x]][1]==x;} int isRoot(int x){ return !(ch[f[x]][1]==x||ch[f[x]][0]==x); } int lson(int x) { return ch[x][0];} int rson(int x){ return ch[x][1];} void add(int x,int delta){ if(!x) return; val[x]+=delta,tag[x]+=delta; } void pushdown(int x){ if(tag[x]) { add(lson(x),tag[x]),add(rson(x),tag[x]); tag[x] = 0; } } void rotate(int x){ int old=f[x],fold=f[old],which=get(x); if(!isRoot(old)) ch[fold][ch[fold][1]==old]=x; ch[old][which]=ch[x][which^1],f[ch[old][which]]=old; ch[x][which^1]=old,f[old]=x,f[x]=fold; } void splay(int x){ int v=0,u=x; sta[++v] = u; while(!isRoot(u)) sta[++v]=f[u],u=f[u]; while(v) pushdown(sta[v--]); u=f[u]; for(int fa;(fa=f[x])!=u;rotate(x)) if(f[fa]!=u) rotate(get(fa)==get(x) ? fa : x); } void Access(int x){ for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y; } void link(int a,int b){ Access(a); splay(a); add(a,val[b]) ,f[b]=a; } void cut(int b){ Access(b),splay(b); add(lson(b),-val[b]),f[lson(b)]=ch[b][0]=0; } }tree; struct SAM{ int last,tot,dis[maxn],ch[maxn][30]; int f[maxn]; void init(){ last=tot=1; } int ins(int c){ int p=last,np=++tot; last=np,dis[np] = dis[p] + 1; tree.val[np] = tree.tag[np] = 1; while(p && !ch[p][c]) ch[p][c] = np,p=f[p]; if(!p) f[np] = 1,tree.link(1,np); else { int q=ch[p][c],nq; if(dis[q] == dis[p] + 1) f[np] = q,tree.link(q,np); else { nq=++tot; tree.val[nq] = 0; dis[nq] = dis[p] + 1; memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq] = f[q]; cur_ans+=dis[nq] - dis[f[nq]]; cur_ans-=(dis[q] - dis[f[q]]); tree.link(f[q],nq),tree.cut(q),tree.link(nq,q),tree.link(nq,np); f[q] = f[np] = nq; cur_ans+=(dis[q] - dis[f[q]]); while(p && ch[p][c] == q) ch[p][c] = nq, p = f[p]; } } cur_ans+=dis[np] - dis[f[np]]; return np; } }sam; struct Node{ int u,c; Node(int u=0,int c=0):u(u),c(c){} }; queue <int> Q; vector <int> mark; vector <Node> G[maxn]; int idx[maxn]; void build_Tree(int n,int st){ for(int i=1;i<n;++i) { int u,v; char c[2]; scanf("%d%d",&u,&v); scanf("%s",c); G[u].push_back(Node(v,c[0]-'0')); mark.push_back(u),mark.push_back(v); } Q.push(st); while(!Q.empty()) { int u =Q.front(); Q.pop(); int sz=G[u].size(); for(int i=0;i<sz;++i){ int v=G[u][i].u; int c=G[u][i].c; sam.last=idx[u]; idx[v]=sam.ins(c); Q.push(v); } } int kk=mark.size(); for(int i=0;i<kk;++i) G[mark[i]].clear(); } int main(){ setIO("input"); int lll,n,m; scanf("%d",&lll); sam.init(),idx[1] = 1; scanf("%d",&n); build_Tree(n,1); scanf("%d",&m); for(int i=1;i<=m;++i) { int opt_idx,a,b; scanf("%d",&opt_idx); if(opt_idx==1) printf("%lld\n",cur_ans); if(opt_idx==2) { scanf("%d%d",&a,&b); build_Tree(b,a); } if(opt_idx==3) { scanf("%s",str); a=strlen(str); b=idx[1]; bool flag = 0; for(int j=0;j<a;++j) { b=sam.ch[b][str[j]-'0']; if(!b) flag = 1; } if(flag) printf("0\n"); else { tree.Access(idx[b]); tree.splay(idx[b]); printf("%d\n",tree.val[idx[b]]); } } } return 0; }