玄关求条,样例已过
查看原帖
玄关求条,样例已过
1367000
Ybll_楼主2025/6/27 16:57
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
struct node
{
	int top,fa,dep,sz,son,id,sum;
}a[N];
struct G
{
	int to,next,val;
}g[N*2];
struct Segment_Tree
{
	int l,r,sum,lazy,lc,rc;
}tree[N*4];
struct ans
{
	int lc,rc,sum;
};
int n,top,head[N*2],num,sum[N];
void add(int u,int v)
{
	g[++top]={v,head[u]};
	head[u]=top;
}
void DFS1(int u,int fa)
{
	a[u].fa=fa;
	a[u].dep=a[fa].dep+1;
	a[u].sz=1;
	for(int i=head[u];i;i=g[i].next)
	{
		if(g[i].to==fa)continue;
		DFS1(g[i].to,u);
		a[u].sz+=a[g[i].to].sz;
		if(a[g[i].to].sz>a[a[u].son].sz)a[u].son=g[i].to;
	}
}
void DFS2(int u,int topx)
{
	a[u].id=++num;
	a[u].top=topx;
	sum[num]=a[u].sum;
	if(!a[u].son)return;
	DFS2(a[u].son,topx);
	for(int i=head[u];i;i=g[i].next)
	{
		if(g[i].to==a[u].fa||g[i].to==a[u].son)continue;
		DFS2(g[i].to,g[i].to);
	}
}
void push_up(int id)
{
	tree[id].sum=tree[id*2].sum+tree[id*2+1].sum-(tree[id*2].lc==tree[id*2+1].rc);
	tree[id].lc=tree[id*2].lc;
	tree[id].rc=tree[id*2+1].rc;
}
void push_down(int id)
{
	if(tree[id].lazy==0)return;
	tree[id*2].lazy=tree[id*2+1].lazy=tree[id].lazy;
	tree[id*2].sum=tree[id*2+1].sum=1;
	tree[id*2].lc=tree[id*2].rc=tree[id*2+1].lc=tree[id*2+1].rc=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int id,int l,int r,int k)
{
	if(tree[id].l>r||tree[id].r<l)return;
	if(tree[id].l>=l&&tree[id].r<=r)
	{
		tree[id].sum=1;
		tree[id].lc=tree[id].rc=k;
		tree[id].lazy=k;
		return;
	}
	push_down(id);
	update(id*2,l,r,k);
	update(id*2+1,l,r,k);
	push_up(id);
}
ans query(int id,int l,int r)
{
	if(tree[id].l>=l&&tree[id].r<=r)return {tree[id].lc,tree[id].rc,tree[id].sum};
	push_down(id);
	int mid=tree[id].l+tree[id].r>>1;
	if(r<=mid)return query(id*2,l,r);
	else if(l>mid)return query(id*2+1,l,r);
	ans ans1=query(id*2,l,r),ans2=query(id*2+1,l,r);
	return {ans1.lc,ans2.rc,ans1.sum+ans2.sum-(ans1.rc==ans2.lc)};
}
void build(int id,int l,int r)
{
	tree[id].l=l;
	tree[id].r=r;
	if(l==r)
	{
		tree[id].lc=tree[id].rc=sum[l];
		tree[id].sum=1;
		return;
	}
	int mid=l+r>>1;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	push_up(id);
}
void update_range(int x,int y,int z)
{
	while(a[x].top!=a[y].top)
	{
		if(a[a[x].top].dep<a[a[y].top].dep)swap(x,y);
		update(1,a[a[x].top].id,a[x].id,z);
		x=a[a[x].top].fa;
	}
	if(a[x].dep>a[y].dep)swap(x,y);
	update(1,a[x].id,a[y].id,z);
}
int query_range(int x,int y)
{
	int res=0,c1=0,c2=0;
	ans sum;
	while(a[x].top!=a[y].top)
	{
		if(a[a[x].top].dep<a[a[y].top].dep)
		{
			swap(x,y);
			swap(c1,c2);
		}
		sum=query(1,a[a[x].top].id,a[x].id);
		res+=sum.sum-(sum.rc==c1);
		c1=sum.lc;
		x=a[a[x].top].fa;
	}
	if(a[x].dep>a[y].dep)swap(x,y);
	sum=query(1,a[x].id,a[y].id);
	return res-(sum.rc==c1)-(sum.lc==c2)+sum.sum;
}
signed main()
{
	int Q;
	cin>>n>>Q;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].sum;
	}
	for(int i=1,u,v;i<n;i++)
	{
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	DFS1(1,0);
	DFS2(1,1);
	build(1,1,n);
	while(Q--)
	{
		char op;
		int x,y,k;
		cin>>op>>x>>y;
		if(op=='Q')cout<<query_range(x,y)<<"\n";
		else
		{
			cin>>k;
			update_range(x,y,k);
		}
	}
	return 0;
}
2025/6/27 16:57
加载中...