萌新求调树剖
查看原帖
萌新求调树剖
287355
1lgorithm楼主2021/11/15 17:29

过样例+0分

#include<iostream>
using namespace std;
struct segment{
	int sum;
	int ping;
	int Lcol,Rcol;
	int l,r,mid,S;
	void clear(){
		S=ping=l=r=mid=Lcol=Rcol=sum=0;
	}
};
segment rev(segment a){
	swap(a.Lcol,a.Rcol);
	return a;
}
int a[100001],A[100001],n,m;
segment t[400001];
segment operator +(segment a,segment b){
	segment c;
	c.clear();
	if(a.S==0) c=b;
	else if(b.S==0) c=a;
	else{
		c.l=a.l,c.r=b.r;
		c.Lcol=a.Lcol,c.Rcol=b.Rcol;
		c.sum=a.sum+b.sum-(a.Rcol==b.Lcol);
		c.mid=c.l+c.r>>1;
		c.S=c.r-c.l+1;	
		c.S=a.S+b.S;
	} 
	return c;
}
void pushup(int p){
	t[p]=t[p<<1]+t[p<<1|1];
}
void build(int *A,int p,int l,int r){
	if(l==r) t[p].sum=1,t[p].l=t[p].r=r,t[p].Lcol=t[p].Rcol=A[l],t[p].S=1;
	else{
		build(A,p<<1,l,l+r>>1),build(A,p<<1|1,(l+r>>1)+1,r);
		pushup(p);
	}
}
void give(int p,int k){
	t[p].Lcol=t[p].Rcol=k;
	t[p].sum=1;
	t[p].ping=k;
}
void pushdown(int p){
	if(t[p].ping==0) return;
	cout<<p<<endl; 
	give(p<<1,t[p].ping),give(p<<1|1,t[p].ping);
	t[p].ping=0;
}
void UPDATE(int p,int L,int R,int k){
	if(t[p].l>=L&&t[p].r<=R) give(p,k);
	else{
		pushdown(p);
		if(t[p].mid>=L) UPDATE(p<<1,L,R,k);
		if(t[p].mid<R) UPDATE(p<<1|1,L,R,k);
		pushup(p);
	}
}
segment QUERY(int p,int L,int R){
	if(t[p].l>=L&&t[p].r<=R) return t[p];
	else{
		pushdown(p);
		segment sum;
		sum.clear();
		if(t[p].mid>=L) sum=sum+QUERY(p<<1,L,R);
		if(t[p].mid<R) sum=sum+QUERY(p<<1|1,L,R);
		return sum;
	}
}
int head[100001],Nxt[200001],ver[200001],edge[200001],tot,cnt;
int top[100001],depth[100001],son[100001];
int S[100001],id[100001],fa[100001];
void add(int x,int y){
	ver[++tot]=y;
	Nxt[tot]=head[x];
	head[x]=tot;
}
void H_DFS(int x,int F){
	fa[x]=F;S[x]=1;
	int maxson=0;	
	for(int i=head[x];i;i=Nxt[i]){
		int y=ver[i];
		if(y==F) continue;
		depth[y]=depth[x]+1;
		H_DFS(y,x);
		S[x]+=S[y];
		if(S[y]>maxson) maxson=S[y],son[x]=y;
	}
}
void ID_DFS(int x,int root){
	top[x]=root;id[x]=++cnt;
	A[cnt]=a[x];
	if(son[x]==0) return;
	ID_DFS(son[x],root);
	for(int i=head[x];i;i=Nxt[i]){
		int y=ver[i];
		if(y==fa[x]||y==son[x]) continue;
		ID_DFS(y,y);
	}
}
void L_UPDATE(int x,int y,int k){
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		UPDATE(1,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(depth[x]>depth[y]) swap(x,y);
	UPDATE(1,id[x],id[y],k);
}
int L_QUERY(int x,int y){
	segment sum1,sum2;
	sum1.clear(),sum2.clear();
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]]){
			sum2=QUERY(1,id[top[y]],id[y])+sum2;
			y=fa[top[y]];
		}
		else{
			sum1=sum1+QUERY(1,id[top[x]],id[x]);
			x=fa[top[x]];
		}
	}
	if(depth[x]>depth[y]) sum2=QUERY(1,id[y],id[x])+sum2;
	else sum1=sum1+QUERY(1,id[x],id[y]);
	return (sum1+rev(sum2)).sum;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	for(int i=1;i<n;++i){
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	depth[1]=1;
	H_DFS(1,0);
	ID_DFS(1,1);
	build(A,1,1,cnt);
	while(m--){
		char op; 
		cin>>op;
		if(op=='C'){
			int l,r,k;
			cin>>l>>r>>k;
			L_UPDATE(l,r,k);
		}
		else{
			int l,r;
			cin>>l>>r;
			cout<<L_QUERY(l,r)<<endl;
		}
	}
}
2021/11/15 17:29
加载中...