树剖 WA0pts 求调
查看原帖
树剖 WA0pts 求调
776582
jhdrgfj楼主2024/4/1 22:14

RT,样例过了。结构体里 v 是颜色段数,sc、tc 是左右端点颜色。

#include<bits/stdc++.h>
#define int long long
#define cyq int 
using namespace std;
const int maxn=500005;
int d[maxn],s[maxn],t[maxn],dfn[maxn],rk[maxn],sz[maxn],fa[maxn],cnt,n,q,k,a[maxn];
struct sgt{
	int v,sc,tc,tg;
}tre[maxn<<2];
cyq mod;
vector<int> g[maxn];

void pu(int id)
{
	tre[id].v=tre[id*2].v+tre[id*2+1].v-(tre[id*2].tc==tre[id*2+1].sc);
	tre[id].sc=tre[id*2].sc;
	tre[id].tc=tre[id*2+1].tc;
}
void pd(int s,int t,int id)
{
	int m=(s+t)>>1;
	if (s!=t && tre[id].tg){
		tre[id*2].v=tre[id*2+1].v=1;
		tre[id*2].sc=tre[id*2].tc=tre[id*2+1].sc=tre[id*2+1].tc=tre[id].tg;
		tre[id*2].tg=tre[id*2+1].tg=tre[id].tg;
		tre[id*2].tg=0;
	}
}
void upd(int l,int r,int s,int t,int id,int k)
{
	if (l<=s && t<=r){
		tre[id].v=1;
		tre[id].sc=tre[id].tc=tre[id].tg=k;
		return ;
	}	
	pd(s,t,id);
	int m=(s+t)/2;
	if (m>=l){
		upd(l,r,s,m,id*2,k);
	}
	if (m<r){
		upd(l,r,m+1,t,id*2+1,k);
	}
	pu(id);
}
sgt ask(int l,int r,int s,int t,int id)
{
	if (l<=s && t<=r){
		return tre[id];
	}	
	pd(s,t,id);
	int m=(s+t)/2;
	sgt sum;
	sum.v=sum.tc=sum.sc=0;
	if (m>=l){
		sum=ask(l,r,s,m,id*2);
	}
	if (m<r){
		sgt k=ask(l,r,m+1,t,id*2+1);
		if (!sum.v){
			sum=k;
		}else{
			sum.v=sum.v+k.v-(sum.tc==k.sc);
			sum.tc=k.tc;
		}
	}
	pu(id);
	return sum;
}

void dfs1(int u)
{
	sz[u]=1;
	for (int v:g[u]){
		if (!d[v]){
			d[v]=d[u]+1;
			fa[v]=u;
			dfs1(v);
			sz[u]+=sz[v];
			if (sz[v]>sz[s[u]]){
				s[u]=v;
			}
		}
	}
}
void dfs2(int u,int hd)
{
	t[u]=hd;
	dfn[u]=++cnt;
	rk[cnt]=u;
	if (!s[u]){
		return ;
	}
	dfs2(s[u],hd);
	for (int v:g[u]){
		if (v==s[u] || v==fa[u]){
			continue;
		}
		dfs2(v,v);
	}
}

void tupd(int u,int v,int k)
{
	while (t[u]!=t[v]){
		if (d[t[u]]<d[t[v]]){
			swap(u,v);
		}
		upd(dfn[t[u]],dfn[u],1,n,1,k);
		u=fa[t[u]];
	}
	if (d[u]>d[v]){
		swap(u,v);
	}
	upd(dfn[u],dfn[v],1,n,1,k);
}
int task(int u,int v)
{
	int sum=0,c1=0,c2=0;
	while (t[u]!=t[v]){
		if (d[t[u]]<d[t[v]]){
			swap(u,v);
			swap(c1,c2);
		}
		sgt k=ask(dfn[t[u]],dfn[u],1,n,1);
		sum+=k.v;
		if (c1==k.sc){
			sum--;
		}
		u=fa[t[u]];
		c1=k.sc;
	}
	if (d[u]>d[v]){
		swap(u,v);
		swap(c1,c2);
	}
	sgt k=ask(dfn[u],dfn[v],1,n,1);
	sum+=k.v;
	if (c1==k.sc){
		sum--;
	}
	if (c2==k.tc){
		sum--;
	}
	return sum;
}

signed main()
{ 
	cin>>n>>q;
	k=1;
	for (int i=1;i<=n;i++){
		cin>>a[i];
	}
	for (int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}	
	fa[k]=k;
	d[k]=1;
	dfs1(k);
	dfs2(k,k);
	for (int i=1;i<=n;i++){
		upd(dfn[i],dfn[i],1,n,1,a[i]);
	}
	while (q--){
		char op;
		int u,v;
		cin>>op>>u>>v;
		if (op=='C'){
			int k;
			cin>>k;
			tupd(u,v,k);
		}else{
			cout<<task(u,v)<<endl;
		}
	}
}
2024/4/1 22:14
加载中...