萌新刚学树链剖分,30分WA求助
查看原帖
萌新刚学树链剖分,30分WA求助
135258
charm1楼主2021/4/14 16:27

RT

#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
int n,m,cnt,now,L,R,lc,rc,ans1,ans2;
int head[maxn],w[maxn];
int dfn[maxn],son[maxn],fa[maxn],top[maxn],dep[maxn],siz[maxn],rev[maxn];
struct edge{
	int v,nxt;
}a[maxn<<1];
struct nod{
	int val,lc,rc,lazy;
}tree[maxn<<2];
inline int read(){
	int ret=0,f=1;	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
	return ret*f;
}
inline void add(int x,int y){
	++cnt;
	a[cnt].v  =y;
	a[cnt].nxt=head[x];
	head[x]=cnt;
}
inline void pushup(int nod){
	int ls=nod<<1,rs=ls+1;
	tree[nod].lc=tree[ls].lc;
	tree[nod].rc=tree[rs].rc;
	tree[nod].val=tree[ls].val+tree[rs].val-(tree[ls].rc==tree[rs].lc);
}
inline void pushdown(int nod){
	int lazy=tree[nod].lazy;    int ls=nod<<1,rs=ls+1;
	if(!lazy)   return;
	tree[nod].lazy=0;
	tree[ls].val=tree[rs].val=1;
	tree[ls].lc=tree[ls].rc=tree[ls].lazy=lazy;
	tree[rs].lc=tree[rs].rc=tree[rs].lazy=lazy;
}
void dfs1(int x,int f){
	fa[x]=f;    siz[x]=1;
	for(int k=head[x];k;k=a[k].nxt){
		int v=a[k].v;
		if(v==f)    continue;
		dep[v]=dep[x]+1;
		dfs1(v,x);  siz[x]+=siz[v];
		if(siz[son[x]]<siz[v])  son[x]=v;
	}
}
void dfs2(int x,int f){
	int s=son[x];
	top[s]=top[x];  dfn[x]=++now;   rev[now]=x;
//	cout<<x<<" "<<f<<" "<<son[x]<<endl;
	if(!son[x]) return;
	dfs2(s,x);
	for(int k=head[x];k;k=a[k].nxt){
		int v=a[k].v;
		if(v==f||v==s)  continue;
		top[v]=v;	dfs2(v,x);
	}
}
void build(int nod,int l,int r){
	if(l==r){
		tree[nod].val=1;
		tree[nod].lc=tree[nod].rc=w[rev[l]];
		return;
	}
	int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
	build(ls,l,mid);    build(rs,mid+1,r);  pushup(nod);
//	cout<<l<<" "<<r<<" "<<tree[nod].val<<endl;
}
void update(int nod,int l,int r,int ll,int rr,int val){
	if(l==ll&&r==rr){
		tree[nod].val=1;
		tree[nod].lc=tree[nod].rc=val;
		tree[nod].lazy=val;
		return;
	}
	pushdown(nod);
	int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
	if(rr<=mid){update(ls,l,mid,ll,rr,val);pushup(nod);return;}
	if(ll>mid){update(rs,mid+1,r,ll,rr,val);pushup(nod);return;}
	update(ls,l,mid,ll,mid,val); update(rs,mid+1,r,mid+1,rr,val);   pushup(nod);
}
int query(int nod,int l,int r,int ll,int rr){
//	cout<<l<<" "<<r<<" "<<ll<<" "<<rr<<" "<<tree[nod].val<<" "<<tree[nod].lc<<" "<<tree[nod].rc<<endl;
	if(l==L)    lc=tree[nod].lc;
	if(r==R)    rc=tree[nod].rc;
	if(l==ll&&r==rr)    return tree[nod].val;
	pushdown(nod);
	int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
	if(rr<=mid) return query(ls,l,mid,ll,rr);
	if(ll>mid)  return query(rs,mid+1,r,ll,rr);
	return query(ls,l,mid,ll,mid)+query(rs,mid+1,r,mid+1,rr)-(tree[ls].rc==tree[rs].lc);
}
void scan(){
	n=read();   m=read();
	for(int k=1;k<=n;k++)   w[k]=read();
	for(int k=1;k<n;k++){
		int x,y;
		x=read();   y=read();
		add(x,y);   add(y,x);
	}
}
void prework(){
	dep[1]=1;   dfs1(1,0);
	top[1]=1;   dfs2(1,0);
	build(1,1,n);
}
int ask(int x,int y){
	int ans=0;  int xc=0,yc=0;
	ans1=0; ans2=0;
	while(top[x]!=top[y]){
		int tx=top[x],ty=top[y];
		if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty),swap(ans1,ans2);
		L=dfn[tx];  R=dfn[x];
		ans+=query(1,1,n,dfn[tx],dfn[x]);
		x=fa[tx];	ans1-=(ans1==rc);    ans1=lc;
	}
	if(dep[x]>dep[y])   swap(x,y),swap(ans1,ans2);
	L=dfn[x];  R=dfn[y];
	ans+=query(1,1,n,dfn[x],dfn[y]);
	ans-=(lc==ans1);    ans-=(rc==ans2);
	return ans;
}
void change(int x,int y,int val){
	while(top[x]!=top[y]){
		int tx=top[x],ty=top[y];
		if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty);
		update(1,1,n,dfn[tx],dfn[x],val);	x=fa[tx];
	}
	if(dep[x]>dep[y])   swap(x,y);
	update(1,1,n,dfn[x],dfn[y],val);
}
void solve(){
	for(int k=1;k<=m;k++){
		char ch=getchar();
		while(!isalpha(ch)) ch=getchar();
		int opt=(ch=='C');	int l,r,val;
	    l=read();   r=read();
	    if(opt){val=read();change(l,r,val);}
	    else{printf("%d\n",ask(l,r));}
	}
}
signed main(){
	scan(); prework();  solve();
	return 0;
}
2021/4/14 16:27
加载中...