萌新刚学树剖,此题全WA,求调qwq,悬赏关注(未过样例),谢谢dalao们
查看原帖
萌新刚学树剖,此题全WA,求调qwq,悬赏关注(未过样例),谢谢dalao们
607952
ZHANGGUIZHI楼主2023/1/9 11:53

调了一上午了,目测是ask有问题,但还是找不出来,以下是代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,w[100002],q,lc,rc;
string s;
int head[100002],ver[200002],nex[200002],tot;//邻接表 
int dep[100002],fa[100002],siz[100002],son[100002];
/*节点深度,节点的父亲,该节点及其子树的长度,该节点的重儿子*/
int top[100002],seg[100002],rev[100002],order;
/*该节点所在重路径的顶部节点,节点在线段树中的位置,对应的节点编号*/
void add(int x,int y){
	nex[++tot]=head[x];
	ver[tot]=y;
	head[x]=tot;
}
void dfs1(int u,int f){
	dep[u]=dep[f]+1;
	fa[u]=f;
	siz[u]=1;
	for(int i=head[u];i;i=nex[i]){
		int v=ver[i];
		if(v==f)continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])
		son[u]=v;
	}
}
void dfs2(int u,int t){
	top[u]=t;
	seg[u]=++order;
	rev[order]=u;
	if(son[u])dfs2(son[u],t);
	for(int i=head[u];i;i=nex[i]){
		int v=ver[i];
		if(v!=fa[u]&&v!=son[u])
		dfs2(v,v);
	}
}
struct node{
	int l,r,sum,cov,lc,rc;
}t[400002];
void pushup(int p){
	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
	if(t[p<<1].rc==t[p<<1|1].lc)t[p].sum--;
	t[p].lc=t[p<<1].lc,t[p].rc=t[p<<1|1].rc;
}
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	t[p].cov=-1;
	if(l==r){
		t[p].lc=t[p].lc=w[rev[l]];
		t[p].sum=1;
		return ;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
}
void spread(int p)
{
	if(t[p].cov==-1)return ;
	t[p<<1].lc=t[p<<1].rc=t[p].cov;
	t[p<<1|1].lc=t[p<<1|1].rc=t[p].cov;
	t[p<<1].sum=1;
	t[p<<1|1].sum=1;
	t[p<<1].cov=t[p].cov;
	t[p<<1|1].cov=t[p].cov;
	t[p].cov=-1;
}
void change(int p,int l,int r,int k)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		t[p].cov=k;
		t[p].lc=t[p].rc=k;
		t[p].sum=1;
		return ;
	}
	spread(p);
	int mid=t[p].l+t[p].r>>1;
	if(l<=mid)change(p<<1,l,r,k);
	if(r>mid)change(p<<1|1,l,r,k);
	pushup(p);
}
void change1(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])
		swap(x,y);
		change(1,seg[top[x]],seg[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
	swap(x,y);
	change(1,seg[x],seg[y],k);
}
int ask(int p,int l,int r){
	if(l>t[p].r||r<t[p].l)
	return 0;
	if(l<=t[p].l&&r>=t[p].r){
		if(l==t[p].l)lc=t[p].l;
		if(r==t[p].r)rc=t[p].r;
		return t[p].sum;
	}
	spread(p);
	int mid=t[p].l+t[p].r>>1,ans=0;
	if(l<=mid)ans=ask(p<<1,l,r);
	if(r>mid)ans+=ask(p<<1|1,l,r);
	if(t[p<<1].rc==t[p<<1|1].lc)
	ans--;
	return ans;
}
int askans(int x,int y){
	int res=0,p1=0,p2=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])
		swap(x,y),swap(p1,p2);
		res=(res+ask(1,seg[top[x]],seg[x]));
		if(rc==p1)res--;
		x=fa[top[x]],p1=lc;
	}
	if(dep[x]>dep[y])
	swap(x,y),swap(p1,p2);
	res=(res+ask(1,seg[x],seg[y]));
	if(lc==p1)res--;
	if(rc==p2)res--;
	return res;
} 
signed main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++)
	cin>>w[i];
	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,order);
	for(int i=1,a,b,c;i<=q;i++){
		cin>>s>>a>>b;
		if(s[0]=='C'){
			cin>>c;
			change1(a,b,c);
		}
		else
		cout<<askans(a,b)<<endl;
	}
	return 0;
}
2023/1/9 11:53
加载中...