萌新刚学树剖,求调55ptWA(马蜂较好)
查看原帖
萌新刚学树剖,求调55ptWA(马蜂较好)
256970
xie_lzh楼主2021/9/28 12:44
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=2139062143;
int n,m,u,v,a,b,c;
char opt;
int w[N],wt[N],siz[N],fa[N],top[N],son[N],id[N],dep[N],cnt;
int head[N],to[N<<1],nxt[N<<1],tot;
int sum[N<<2],lc[N<<2],rc[N<<2],laz[N<<2];
int nlc,nrc,pos1,pos2;
int read()
{
	int r=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		r=(r<<1)+(r<<3)+c-48;
		c=getchar();
	}
	return r*f;
}
void add(int u,int v)
{
	to[++tot]=v;
	nxt[tot]=head[u];
	head[u]=tot;
}
int ls(int x){return x<<1; }
int rs(int x){return x<<1|1; }
void push_up(int x)
{
	sum[x]=sum[ls(x)]+sum[rs(x)];
	if(rc[ls(x)]==lc[rs(x)]) sum[x]--;
	lc[x]=lc[ls(x)];
	rc[x]=rc[rs(x)];
}
void build(int p,int l,int r)
{
	if(l==r)
	{
		sum[p]=1;
		lc[p]=wt[l];
		rc[p]=wt[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	push_up(p);
}
void push_down(int x)
{
	laz[ls(x)]=laz[x];
	laz[rs(x)]=laz[x];
	sum[ls(x)]=sum[rs(x)]=1;
	lc[ls(x)]=rc[ls(x)]=laz[x];
	lc[rs(x)]=rc[rs(x)]=laz[x];
	laz[x]=INF;
}
void update(int p,int l,int r,int L,int R,int k)
{
	if(L<=l&&r<=R)
	{
		sum[p]=1;
		lc[p]=rc[p]=k;
		laz[p]=k;
		return ;
	}
	if(laz[p]!=INF) push_down(p);
	int mid=(l+r)>>1;
	if(L<=mid) update(ls(p),l,mid,L,R,k);
	if(R>mid)  update(rs(p),mid+1,r,L,R,k);
	push_up(p);
}
void dfs1(int f,int now,int deep)
{
	fa[now]=f;
	dep[now]=deep;
	siz[now]=1;
	int hson=-1;
	for(int i=head[now];i;i=nxt[i])
	{
		int v=to[i];
		if(v==f) continue;
		dfs1(now,v,deep+1);
		siz[now]+=siz[v];
		if(siz[v]>hson)
		{
			hson=siz[v];
			son[now]=v;
		}
	}
}
void dfs2(int now,int topf)
{
	id[now]=++cnt;
	wt[cnt]=w[now];
	top[now]=topf;
	if(son[now]==0) return ;
	dfs2(son[now],topf);
	for(int i=head[now];i;i=nxt[i])
	{
		int v=to[i];
		if(v==fa[now]||v==son[now]) continue;
		dfs2(v,v);
	}
}
int query(int p,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)
	{
		if(L==l) nlc=lc[p];
		if(r==R) nrc=rc[p];
		return sum[p];
	}
	if(laz[p]!=INF) push_down(p);
	int mid=(l+r)>>1,lsr=0,rsr=0,res=0;
	if(L<=mid) lsr=query(ls(p),l,mid,L,R);
	if(R>mid)  rsr=query(rs(p),mid+1,r,L,R);
	res=lsr+rsr;
	if(lsr==0||rsr==0) return res;
	else if(rc[ls(p)]==lc[rs(p)]) res--;
	return res;
}
void updrange(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(1,1,n,id[x],id[y],k);
}
int qrange(int x,int y)
{
	int ans=0;
	pos1=pos2=INF;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(pos1,pos2);
		ans+=query(1,1,n,id[top[x]],id[x]);
		if(nrc==pos1) ans--;
		x=fa[top[x]];
		pos1=nlc;
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=query(1,1,n,id[x],id[y]);
	if(nlc==pos1) ans--;
	if(nrc==pos2) ans--;
	return ans;
}
int main()
{
	memset(laz,0x7f,sizeof laz);
	n=read(); m=read();
	for(int i=1;i<=n;i++)
		w[i]=read();
	for(int i=1;i<n;i++)
	{
		u=read(); v=read();
		add(u,v);
		add(v,u);
	}
	dfs1(0,1,0);
	dfs2(1,1);
	build(1,1,n);
	while(m--)
	{
		cin>>opt;
		if(opt=='C')
		{
			a=read(); b=read(); c=read();
			updrange(a,b,c);
		}
		if(opt=='Q')
		{
			a=read(); b=read();
			printf("%d\n",qrange(a,b));
		}
	}
	return 0;
}

2021/9/28 12:44
加载中...