这题理论上可以用ETT,但是用LCT建虚点可以解决这个问题。
对于最晚的操作1建立一个虚点,然后把操作0挂上去。
#include<bits/stdc++.h> const int N=4e5+5; using namespace std; struct Link_Cut_Tree{ int size[N],w[N],c[N][2],fa[N],cnt,rev[N],q[N]; inline void newnode(int x){++cnt;size[cnt]=w[cnt]=x;} inline bool isroot(int x){return (c[fa[x]][1]!=x&&c[fa[x]][0]!=x)||!x;} inline void pushup(int x){size[x]=size[c[x][0]]+size[c[x][1]]+w[x];} inline void pushdown(int x){ int l=c[x][0],r=c[x][1]; if(rev[x]){ rev[l]^=1;rev[r]^=1;rev[x]^=1; swap(c[x][0],c[x][1]); } } inline void rotate(int x){ int y=fa[x],z=fa[y],l,r; if(c[y][0]==x)l=0;else l=1;r=l^1; if(!isroot(y)){if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;} fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; pushup(y);pushup(x); } inline void splay(int x){ int top=1;q[top]=x; for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; for(int i=top;i;i--)pushdown(q[i]); while(!isroot(x)){ int y=fa[x],z=fa[y]; if(!isroot(y)){ if((c[y][0]==x)^(c[z][0]==y))rotate(x); else rotate(y); }rotate(x); } pushup(x); } inline int access(int x){int t=0;for(;x;t=x,x=fa[x])splay(x),c[x][1]=t,pushup(x);return t;} inline void cut(int x){access(x),splay(x),fa[c[x][0]]=0,c[x][0]=0;pushup(x);} inline void link(int x,int y){splay(x);fa[x]=y;} }T; struct Opt{ int pos,opt,x,y; Opt(int pos=0,int opt=0,int x=0,int y=0):pos(pos),opt(opt),x(x),y(y){} }a[N]; bool cmp(Opt a,Opt b){return a.pos==b.pos?a.opt<b.opt:a.pos<b.pos;} int n,m,op[N],ed[N],b[N],tot=1,ans[N],vis[N],top; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();m=read();int now=0; T.newnode(1);T.newnode(0);T.link(2,1);now=2; b[1]=1;op[1]=1;ed[1]=n; for(int i=1;i<=m;i++){ int opt=read(),l=read(),r=read(); if(opt==0){ ++tot;T.newnode(1); b[tot]=T.cnt;op[tot]=l;ed[tot]=r; a[++top]=Opt(1,i-m,T.cnt,now); } else if(opt==1){ int k=read();l=max(op[k],l);r=min(r,ed[k]); if(l<=r){ T.newnode(0);T.link(T.cnt,now); a[++top]=Opt(l,i-m,T.cnt,b[k]); a[++top]=Opt(r+1,i-m,T.cnt,now); now=T.cnt; } } else{ int k=read();vis[i]=1; a[++top]=Opt(l,i,b[r],b[k]); } } sort(a+1,a+top+1,cmp);int k=1,t=0; for(int i=1;i<=n;i++){ for(;a[k].pos==i;k++){ if((t=a[k].opt)>0){ int x=a[k].x,y=a[k].y; T.access(x);T.splay(x);ans[t]+=T.size[x]; int lca=T.access(y);T.splay(y);ans[t]+=T.size[y]; T.access(lca);T.splay(lca);ans[t]-=T.size[lca]*2; }else{T.cut(a[k].x);T.link(a[k].x,a[k].y);} } } for(int i=1;i<=m;i++)if(vis[i])printf("%d ",ans[i]); }