刚学OI的萌新求助简单树上问题
查看原帖
刚学OI的萌新求助简单树上问题
455490
Sharpsmile楼主2024/2/25 17:02

似在了第三种询问,因该能够保证线段树的部分没有问题。应该是改颜色的时候出现了问题?求大佬帮帮qwq

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define pii pair<int,int>
#define p1(x) (x).first
#define p2(x) (x).second
int n,q;
int C[200300];
int xc[200300];
vector<int>g[100300];
int d[100300],f[100300],tp[100300],dfn[100300],siz[100300],loc[100300],hs[100300];
map<int,int>mp[100300];
struct node {
	int s,lid,rid,mx,cnt,tgmx,tgid;
	friend node operator +(const node A,const node B){
		if(A.s==-1)return B;
		if(B.s==-1)return A;
		return {A.s+B.s,A.lid,B.rid,max(A.mx,B.mx),A.cnt+B.cnt-(A.rid==B.lid),0,0};
	}	
	inline void add_mx(int x){
		tgmx+=x;
		mx+=x;
	}
	inline void cover_id(int x){
		tgid=x;
		lid=rid=x;
		cnt=1;
	}
}T[100300<<2];
inline void upd(int x){
	T[x]=T[lc(x)]+T[rc(x)];
}
inline void pd(int x){
	if(T[x].tgmx){
		T[lc(x)].add_mx(T[x].tgmx);
		T[rc(x)].add_mx(T[x].tgmx);
		T[x].tgmx=0;
	}
	if(T[x].tgid){
		T[lc(x)].cover_id(T[x].tgid);
		T[rc(x)].cover_id(T[x].tgid);
		T[x].tgid=0;
	}
}
int col=0;
inline void bd(int x,int l,int r){
	if(l==r){
		T[x]={1,l,l,d[loc[l]],1,0,0};
		return ;
	}
	int mid=l+r>>1;
	bd(lc(x),l,mid);
	bd(rc(x),mid+1,r);
	upd(x);
}
inline void cov(int x,int l,int r,int L,int R,int c){
	if(L<=l&&r<=R){
		T[x].cover_id(c);
		return ;
	}
	pd(x);
	int mid=l+r>>1;
	if(L<=mid)cov(lc(x),l,mid,L,R,c);
	if(R>mid)cov(rc(x),mid+1,r,L,R,c);
	upd(x);	
}
inline void add(int x,int l,int r,int L,int R,int c){
	if(L<=l&&r<=R){
		T[x].add_mx(c);
		return ;
	}
	pd(x);
	int mid=l+r>>1;
	if(L<=mid)add(lc(x),l,mid,L,R,c);
	if(R>mid)add(rc(x),mid+1,r,L,R,c);
	upd(x);
}
queue<int>Q;
inline void ADD(int x,int k){
	add(1,1,n,dfn[x],dfn[x]+siz[x]-1,k);
}
inline void ers(int x,int l,int r,int L,int R){
	if(T[x].s==0)return ;
	if(l==r){
		T[x].s=0;
		Q.push(C[loc[l]]);
		C[loc[l]]=0;
		ADD(loc[l],-1);
		return ;
	}
	pd(x);
	int mid=l+r>>1;
	if(L<=mid)ers(lc(x),l,mid,L,R);
	if(R>mid)ers(rc(x),mid+1,r,L,R);
	upd(x);
}
inline void ins(int x,int l,int r,int c){
	if(l==r){
		if(T[x].s)return ;
		T[x].s=1;
		ADD(loc[l],1);
		return ;
	}
	pd(x);
	int mid=l+r>>1;
	if(c<=mid)ins(lc(x),l,mid,c);
	else ins(rc(x),mid+1,r,c);
	upd(x);
}
inline node gt(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return T[x];
	pd(x);
	int mid=l+r>>1;
	bool lp=L<=mid,rp=R>mid;
	if(lp&&rp)return gt(lc(x),l,mid,L,R)+gt(rc(x),mid+1,r,L,R);
	if(lp)return gt(lc(x),l,mid,L,R);
	if(rp)return gt(rc(x),mid+1,r,L,R);
	assert(0); 
}
int tk;
inline void dfs(int u){
	siz[u]=1;
	d[u]=d[f[u]]+1;
	for(int v:g[u])
	if(v!=f[u]){
		f[v]=u;
		dfs(v);
		siz[u]+=siz[v];
		if(siz[v]>siz[hs[u]])hs[u]=v;
	}
}
inline void dfs(int u,int t){
	tp[u]=t;
	loc[dfn[u]=++tk]=u;
	if(hs[u])dfs(hs[u],t);
	for(int v:g[u])
	if(v!=f[u]&&v!=hs[u])
		dfs(v,v);
	for(int v:g[u])
		if(v!=f[u])
			mp[u][dfn[v]+siz[v]-1]=v;
}	
inline node rev(node A){
	swap(A.lid,A.rid);
	return A;
} 
inline int LCA(int x,int y){
	while(tp[x]!=tp[y]){
		if(d[tp[x]]<d[tp[y]])swap(x,y);
		x=f[tp[x]];
	}
	if(d[x]<d[y])swap(x,y);
	return y;
}
inline void mod(int x,int c){
	xc[c]=x;
	while(x){
		cov(1,1,n,dfn[tp[x]],dfn[x],c);
		ers(1,1,n,dfn[tp[x]],dfn[x]);
		x=f[tp[x]];
	}
	ins(1,1,n,dfn[1]);
	C[1]=c;
	x=xc[c];
	while(!Q.empty()){
		int c=Q.front();
		Q.pop();
		int L=LCA(x,xc[c]);
		if(L==xc[c]){xc[c]=-1;continue;}
		L=mp[L].lower_bound(dfn[xc[c]])->second; 
//		cout<<c<<" "; 
		C[L]=c;
		ins(1,1,n,dfn[L]);
	}
	
}
inline node gt(int x,int y){
	node X,Y;
	X.s=Y.s=-1;
	while(tp[x]!=tp[y]){
		if(d[tp[x]]>d[tp[y]]){
			X=X+rev(gt(1,1,n,dfn[tp[x]],dfn[x]));
			x=f[tp[x]];
		}
		else{
			Y=gt(1,1,n,dfn[tp[y]],dfn[y])+Y;
			y=f[tp[y]];
		}
	}
	if(d[x]>d[y])X=X+rev(gt(1,1,n,dfn[y],dfn[x]));
	else Y=gt(1,1,n,dfn[x],dfn[y])+Y;
	return X+Y;
}
signed main(){
//	freopen("ex_yoimiya4.in","r",stdin);
//	freopen("yoimiya.out","w",stdout);
    ios::sync_with_stdio(0);
	cin>>n>>q;
	col=n;	
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1);
	dfs(1,1);
	for(int i=1;i<=n;i++)
		xc[i]=i,C[i]=i;
	bd(1,1,n);
	while(q--){
		int op;
		cin>>op;
		if(op==1){
			int x;
			cin>>x;
			mod(x,++col);
		}
		else if(op==2){
			int x,y;
			cin>>x>>y;
			cout<<gt(x,y).cnt<<endl;
		}
		else {
			int x;
			cin>>x;
			cout<<gt(1,1,n,dfn[x],dfn[x]+siz[x]-1).mx<<endl;
			
		}
	}	
	cout.flush();
    return 0;
} 
/*

5 2
1 2
2 3
3 4
3 5
1 4
3 3
*/
2024/2/25 17:02
加载中...