0分求条,玄关
查看原帖
0分求条,玄关
1192554
ryderyang楼主2025/8/1 13:32
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
vector<int> tree[N];
int col[N];
int size[N];
int dep[N];
int fa[N];
int son[N];
int top[N];
int pos[N];
int new_id=0;
char opt;
struct SegementTreeNode
{
	int l,r,num,tag;
	int lc,rc;
}seg_tree[N<<2];
int Lc,Rc;
void dfs1(int u,int father,int depth)
{
	size[u]=1;
	fa[u]=father;
	dep[u]=depth;
	son[u]=0;
	for(auto v:tree[u])
	{
		if(v==father) continue;
		dfs1(v,u,depth+1);
		size[u]+=size[v];
		if(size[v]>size[son[u]])
		son[u]=v;
	}
}
void dfs2(int u,int top_node)
{
	pos[u]=++new_id;
	top[u]=top_node;
	if(son[u]) dfs2(son[u],top_node);
	for(auto v:tree[u])
	{
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
void push_down(int u)
{
	if(seg_tree[u].tag)
	{
		seg_tree[u<<1].tag=seg_tree[u].tag;
		seg_tree[u<<1].num=1;
		seg_tree[u<<1].lc = seg_tree[u<<1].rc = seg_tree[u].lc;
		seg_tree[u<<1|1].tag=seg_tree[u].tag;
		seg_tree[u<<1|1].num=1;
		seg_tree[u<<1|1].lc = seg_tree[u<<1|1].rc = seg_tree[u].lc;
		seg_tree[u].tag=0;		
	}
}
void push_up(int u)
{
	seg_tree[u].lc=seg_tree[u<<1].lc;
	seg_tree[u].rc=seg_tree[u<<1|1].rc;
	seg_tree[u].num=seg_tree[u<<1].num+seg_tree[u<<1|1].num;
	if(seg_tree[u<<1].rc==seg_tree[u<<1|1].lc) seg_tree[u].num--;
}
void build(int u,int l,int r)
{
	seg_tree[u].l=l;
	seg_tree[u].r=r;
	seg_tree[u].num=seg_tree[u].tag=0;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
}
void update(int u,int l,int r,int color)
{
	if(seg_tree[u].l==l&&seg_tree[u].r==r)
	{
		seg_tree[u].tag=1;
		seg_tree[u].num=1;
		seg_tree[u].lc=seg_tree[u].rc=color;
		return;
	}
	push_down(u);
	int mid=(seg_tree[u].l+seg_tree[u].r)>>1;
	if(r<=mid) update(u<<1,l,r,color);
	else if(l>mid) update(u<<1|1,l,r,color);
	else update(u<<1,l,mid,color),update(u<<1|1,mid+1,r,color);
	push_up(u);
}
int query(int u,int l,int r,int L,int R)
{
	if(seg_tree[u].l==L) Lc=seg_tree[u].lc;
	if(seg_tree[u].r==R) Rc=seg_tree[u].rc;
	if(seg_tree[u].l==l&&seg_tree[u].r==r) return seg_tree[u].num;
	int mid=(seg_tree[u].l+seg_tree[u].r)>>1;
	if(r<=mid) return query(u<<1,l,r,L,R);
	else if(l>mid) return query(u<<1|1,l,r,L,R);
	else return (query(u<<1,l,mid,L,R)+query(u<<1|1,mid+1,r,L,R))-((seg_tree[u<<1].rc==seg_tree[u<<1|1].lc)? 1:0);
}
int path_operation(int u,int v,int type,int color=0)
{
	int res=0;
	int _=-1,__=-1;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])
		{
			swap(u,v);
			if(type==2) swap(_,__);
		}
		if(type==1) update(1,pos[top[u]],pos[u],color);
		else res+=query(1,pos[top[u]],pos[u],pos[top[u]],pos[u])-((Rc==_)? 1:0),_=Lc;
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])
	{
		swap(u,v);
		if(type==2) swap(_,__);
	}
	if(type==1) update(1,pos[u],pos[v],color);
	else res+=query(1,pos[u],pos[v],pos[u],pos[v])-((Lc==__)? 1:0)-((Rc==_)? 1:0);
	return res;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>col[i];
	for(int i=1,u,v;i<=n-1;i++)
	{
		cin>>u>>v;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	dfs1(1,0,1);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=n;i++) update(1,pos[i],pos[i],col[i]);
	while(m--)
	{
		cin>>opt;
		if(opt=='C')
		{
			int u,v,c;
			cin>>u>>v>>c;
			path_operation(u,v,1,c);
		}
		else
		{
			int u,v;
			cin>>u>>v;
			cout<<path_operation(u,v,2)<<endl;
		}
	}
	return 0;
}
2025/8/1 13:32
加载中...