悬关 只对了第8个点(qwq)
查看原帖
悬关 只对了第8个点(qwq)
541499
StarRoam楼主2024/3/28 21:06
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n,m,a[N];
int deep[N],size[N],hs[N],dfn[N],trk[N],fat[N],top[N],cnt;
vector<int> to[N];
struct Segment_Tree{
	long long tree[N<<6],tag[N<<6],ls[N<<6],rs[N<<6];
	void down(int l,int r,int pos)
	{
		if(tag[pos]==0||l==r) 
		{
			if(l==r&&tag[pos]!=0) 
			{
				a[trk[l]]=tag[pos];
			}
			return;
		}
		tree[pos*2]=tree[pos*2+1]=1;
		tag[pos*2]=tag[pos*2+1]=tag[pos];
		ls[pos*2]=rs[pos*2]=tag[pos*2];
		ls[pos*2+1]=rs[pos*2+1]=tag[pos*2+1];
		tag[pos]=0;
	}
	void up(int l,int r,int pos)
	{
		if(l==r) return;
		tree[pos]=tree[pos*2]+tree[pos*2+1];
		if(rs[pos*2]==ls[pos*2+1]) tree[pos]--;
		ls[pos]=ls[pos*2],rs[pos]=rs[pos*2+1];
	}
	void build(int l,int r,int pos)
	{
		if(l==r)
		{
			tree[pos]=1;
			ls[pos]=rs[pos]=a[trk[l]];
			return;
		}
		int mid=(l+r)>>1;
		build(l,mid,pos*2);
		build(mid+1,r,pos*2+1);
		up(l,r,pos);
	}
	int query(int l,int r,int ql,int qr,int pos)
	{
		if(ql<=l&&r<=qr) return tree[pos];
		down(l,r,n);
		int mid=(l+r)>>1;
		int ans=0,cl=0,cr=0;
		if(ql<=mid) 
		{
			ans+=query(l,mid,ql,qr,pos*2);
			cl=rs[pos*2];
		}
		if(qr>mid)
		{
			ans+=query(mid+1,r,ql,qr,pos*2+1);
			cr=ls[pos*2+1];
		}
		up(l,r,pos);
		if(cl==cr&&cl!=0&&cr!=0) ans--;
		return ans;
	}
	void update(int l,int r,int ql,int qr,int pos,int w)
	{
		if(ql<=l&&r<=qr)
		{
			ls[pos]=rs[pos]=tag[pos]=w,tree[pos]=1;
			return ;
		}
		down(l,r,pos);
		int mid=(l+r)>>1;
		if(ql<=mid) update(l,mid,ql,qr,pos*2,w);
		if(qr>mid) update(mid+1,r,ql,qr,pos*2+1,w);
		up(l,r,pos);
	}
	int find(int l,int r,int q,int pos)
	{
		if(l==r) 
		{
			if(tag[pos]!=0) a[trk[l]]=tag[pos];
			return a[trk[l]];
		}
		down(l,r,pos);
		int mid=(l+r)>>1;
		if(q<=mid) return find(l,mid,q,pos*2);
		else return find(mid+1,r,q,pos*2+1);
		up(l,r,pos);
	}
}T;
void dfs1(int pos,int fa)
{
	int maxn=0;
	deep[pos]=deep[fa]+1,size[pos]=1,fat[pos]=fa;
	for(int i=0;i<to[pos].size();i++)
	{
		int v=to[pos][i];
		if(v==fa) continue;
		dfs1(v,pos);
		if(size[v]>maxn) maxn=size[v],hs[pos]=v;
		size[pos]+=size[v];
	}
}
void dfs2(int pos,int topx,int fa)
{
	top[pos]=topx,dfn[pos]=++cnt,trk[cnt]=pos;
	if(hs[pos]==0) return;
	dfs2(hs[pos],topx,pos);
	for(int i=0;i<to[pos].size();i++)
	{
		int v=to[pos][i];
		if(v==fa||v==hs[pos]) continue;
		dfs2(v,v,pos);
	}
}
int require(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans+=T.query(1,n,dfn[top[x]],dfn[x],1);
		int ka=T.find(1,n,dfn[top[x]],1);
		int kb=T.find(1,n,dfn[fat[top[x]]],1);
		if(ka==kb) ans--;
		x=fat[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
//	cout<<ans<<"aaa\n";
	ans+=T.query(1,n,dfn[x],dfn[y],1);
//	cout<<ans<<"aaa\n";
	return ans;
}
void updated(int x,int y,int z)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		T.update(1,n,dfn[top[x]],dfn[x],1,z);
		x=fat[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	T.update(1,n,dfn[x],dfn[y],1,z);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		to[u].push_back(v);
		to[v].push_back(u);
	}
	dfs1(1,0);dfs2(1,1,0);
	T.build(1,n,1);
	while(m--)
	{
		int x,y,z;
		char opt;
		cin>>opt;
		if(opt=='Q')
		{
			cin>>x>>y;
			cout<<require(x,y)<<"\n";
		}
		else
		{
			cin>>x>>y>>z;
			updated(x,y,z);
		}
	}
	return 0;
}
2024/3/28 21:06
加载中...