树剖求吊
查看原帖
树剖求吊
754467
f_hxr_楼主2023/10/1 10:24

rt

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int N,QWQ;
struct SegmentTree{
	struct node
	{int ls,rs,L,R,dat,setv=-1;}dat[400005];
	#define ls(p) (dat[p].ls)
	#define rs(p) (dat[p].rs)
	#define len(p) (dat[p].R-dat[p].L+1)
	void pushup(int p)
	{dat[p].dat=dat[ls(p)].dat+dat[rs(p)].dat;}
	void pushdown(int p){
		if(dat[p].setv!=-1){
			dat[ls(p)].dat=dat[p].setv*len(ls(p));
			dat[rs(p)].dat=dat[p].setv*len(rs(p));
			dat[ls(p)].setv=dat[rs(p)].setv=dat[p].setv;
			dat[p].setv=-1;
		}
	}
	void build(int p,int L,int R,int arr[]){
		dat[p].L=L;dat[p].R=R;
		if(L==R){dat[p].dat=arr[L];return;}
		int mid=(L+R)>>1;
		ls(p)=(p<<1);rs(p)=(p<<1|1);
		build(ls(p),L,mid,arr);build(rs(p),mid+1,R,arr);
		pushup(p);
	}
	int QueryPoint(int p,int inx){
		int L=dat[p].L,R=dat[p].R;
		if(L==R)return dat[p].dat;
		int mid=(L+R)>>1;
		if(inx<=mid)return QueryPoint(ls(p),inx);
		else return QueryPoint(rs(p),inx);
	}
	void SetRange(int p,int ql,int qr,int xx){
		int L=dat[p].L,R=dat[p].R;
		if(ql<=L&&R<=qr)
		{dat[p].dat=xx*len(p);dat[p].setv=xx;return;}
		pushdown(p);		
		int mid=(L+R)>>1;
		if(ql<=mid)SetRange(ls(p),ql,qr,xx);
		if(mid+1<=qr)SetRange(rs(p),ql,qr,xx);
		pushup(p); 
	}
	int QueryRange(int p,int ql,int qr){
		int L=dat[p].L,R=dat[p].R;
		if(ql<=L&&R<=qr){return dat[p].dat;}
		pushdown(p);
		int mid=(L+R)>>1,ret=0;
		if(ql<=mid)ret+=QueryRange(ls(p),ql,qr);
		if(mid+1<=qr)ret+=QueryRange(rs(p),ql,qr);
		return ret;
	}
};
struct SLPF{
	int a[maxn],val[maxn],dfs_clock=0;
	int head[maxn],nxt[maxn],to[maxn],cnt_edge;
	int Fa[maxn],dep[maxn],sz[maxn],id[maxn],Hd[maxn],Hson[maxn];
	SegmentTree SegTree; 
	void AddEdge(int u,int v){
		nxt[++cnt_edge]=head[u];to[cnt_edge]=v;head[u]=cnt_edge;
		nxt[++cnt_edge]=head[v];to[cnt_edge]=u;head[v]=cnt_edge;
	}
	void dfs1(int u,int fa){
		Fa[u]=fa;dep[u]=dep[fa]=1;sz[u]=1;
		int MaxSonW=-1;
		for(int i=head[u];i;i=nxt[i]){
			if(to[i]==fa)continue;
			dfs1(to[i],u);sz[u]+=sz[to[i]];
			if(sz[to[i]]>MaxSonW)
				MaxSonW=sz[to[i]],Hson[u]=to[i];
		}
	}
	void dfs2(int u,int Top){
		Hd[u]=Top;id[u]=++dfs_clock;
		val[dfs_clock]=a[u];
		if(!Hson[u])return;
		dfs2(Hson[u],Top);
		for(int i=head[u];i;i=nxt[i]){
			if(to[i]==Fa[u]||to[i]==Hson[u])continue;
			dfs2(to[i],to[i]);
		}
	}
	void init(){
		scanf("%d",&N);
		for(int i=1;i<N;i++){
			int a,b;scanf("%d%d",&a,&b);
			AddEdge(a,b);
		}
		dfs1(1,0);dfs2(1,1);SegTree.build(1,1,dfs_clock,val);
	}
	void SetSubTree(int u,int xx)
	{SegTree.SetRange(1,u,id[u]+sz[u]-1,xx);}
	int QuerySubTree(int u)
	{return SegTree.QueryRange(1,id[u],id[u]+sz[u]-1);}
	void SetToRoot(int u,int xx){
		while(Hd[u]!=1){
			SegTree.SetRange(1,id[Hd[u]],id[u],xx);
			u=Fa[Hd[u]];
		}
		SegTree.SetRange(1,1,id[u],xx);
	}
	int QueryToRoot(int u){
		int ret=0;
		while(Hd[u]!=1){
			ret+=SegTree.QueryRange(1,id[Hd[u]],id[u]);
			u=Fa[Hd[u]]; 
		}
		ret+=SegTree.QueryRange(1,1,id[u]);return ret;
	}
	void Install(int u){SetToRoot(u,1);}
	void UnInstall(int u){SetSubTree(u,0);}
	void QueryInstall(int u){
		if(SegTree.QueryPoint(1,id[u])==1)
		{printf("0\n");return;}
		int Installed=QueryToRoot(u);
		printf("%d\n",dep[u]-Installed);
	}
	void QueryUnInstall(int u){
		if(SegTree.QueryPoint(1,id[u])==0)
		{printf("0");return;}
		printf("%d\n",sz[u]-1-QuerySubTree(u));
	}
	void Query(){
		char s[114];scanf("%s",s);
		int xx;scanf("%d",xx);xx++;
		if(s[0]=='i'){
			QueryInstall(xx);
			Install(xx);
		}else if(s[0]=='u'){
			QueryUnInstall(xx);
			UnInstall(xx);
		}
	}
}Tree;
int main(){
	Tree.init();
	scanf("%lld",&QWQ);
	while(QWQ--)Tree.Query();
	return 0;
}
2023/10/1 10:24
加载中...