只过了hack球条 (自认为马蜂良好)
查看原帖
只过了hack球条 (自认为马蜂良好)
798144
SukiYuri楼主2024/6/18 15:45
#include<cstdio>
const int maxn=1e5+5;
int head[maxn],dep[maxn],Fa[maxn],siz[maxn];
int id[maxn],iid[maxn],top[maxn],col[maxn],cnt;
int n,m;
struct edge{
	int to,nxt;
	edge(int x=0,int y=0):to(x),nxt(y){}
}adj[maxn<<1];
inline void adde(int u,int v){
	adj[++cnt]=edge(v,head[u]);
	head[u]=cnt;
}

void dfs1(int cu,int fa){
	dep[cu]=dep[fa]+1;
	Fa[cu]=fa;
	siz[cu]=1;
	for(int i=head[cu];i;i=adj[i].nxt){
		int to=adj[i].to;
		if(to==fa)continue;
		dfs1(to,cu);
		siz[cu]+=siz[to];
	}
}
void dfs2(int cu,int fir){
	id[cu]=++cnt;
	iid[cnt]=cu;
	top[cu]=fir;
	int hson=0;
	for(int i=head[cu];i;i=adj[i].nxt){
		int to=adj[i].to;
		if(to==Fa[cu])continue;
		if(siz[hson]<siz[to])
			hson=to;
	}
	if(hson)dfs2(hson,fir);
	for(int i=head[cu];i;i=adj[i].nxt){
		int to=adj[i].to;
		if(to==Fa[cu]||to==hson)continue;
		dfs2(to,to);
	}
}
struct NodeSeg{
	int l,r,val,tag;
	NodeSeg(int a=0,int b=0,int c=0,int d=0):
		l(a),r(b),val(c),tag(d){}
	void print(){
		printf("%d %d %d %d\n",l,r,val,tag);
	}
}seg[maxn<<2];
inline NodeSeg comb(NodeSeg a,NodeSeg b){
	if(!a.l)return b;
	if(!b.l)return a;
	return NodeSeg(a.l,b.r,a.val+b.val-(a.r==b.l));
}
void build(int k,int l,int r){
	if(l==r){
		seg[k].l=seg[k].r=col[iid[l]];
		seg[k].val=1;
	} else {
		int mid=(l+r)>>1;
		build(k<<1,l,mid);
		build(k<<1|1,mid+1,r);
		seg[k]=comb(seg[k<<1],seg[k<<1|1]);
	}
	// printf("%d %d %d ",k,l,r);
	// seg[k].print();
}
void pushdown(int k){
    if(!seg[k].tag)return;
	int lc=k<<1,rc=k<<1|1;
	seg[rc].tag=seg[lc].tag=seg[k].tag;
	seg[lc].l=seg[rc].l=seg[k].l;
	seg[lc].r=seg[rc].r=seg[k].r;
	seg[lc].val=seg[rc].val=1;
	seg[k].tag=0;
}
void update(int k,int l,int r,int L,int R,int v){
    if(R<l||r<L)return;
	if(L<=l&&r<=R){
		seg[k].tag=v;
		seg[k].val=1;
		seg[k].l=seg[k].r=v;
	} else {
		pushdown(k);
		int mid=(l+r)>>1;
		if(L<=mid) update(k<<1,l,mid,L,R,v);
		if(mid<R) update(k<<1|1,mid+1,r,L,R,v);
		seg[k]=comb(seg[k<<1],seg[k<<1|1]);
	}
	// seg[k].print();
}
void modify(int u,int v,int col){
	while(top[u]!=top[v]){
		if(dep[top[u]]>dep[top[v]]){
			update(1,1,n,id[top[u]],id[u],col);
			u=Fa[top[u]];
		} else {
			update(1,1,n,id[top[v]],id[v],col);
			v=Fa[top[v]];
		}
	}
	if(id[u]>id[v]){
	    int t=u;
	    u=v, v=t;
	}
	update(1,1,n,id[u],id[v],col);
}
NodeSeg query(int k,int l,int r,int L,int R){
	if(L<=l&&r<=R)
		return seg[k];
	NodeSeg res;
	if(R<l||r<L)return res;
	pushdown(k);
	int mid=(l+r)>>1;
	if(L<=mid) res=comb(res,query(k<<1,l,mid,L,R));
	if(mid<R) res=comb(res,query(k<<1|1,mid+1,r,L,R));
	return res;
}
int path_col(int u,int v){
	NodeSeg res1,res2,res;
	while(top[u]!=top[v]){
		if(dep[top[u]]>dep[top[v]]){
			NodeSeg ans=query(1,1,n,id[top[u]],id[u]);
			res1=comb(ans,res1);
			// printf("%d %d ",id[top[u]],id[u]);
			// ans.print();
			// res1.print();
			u=Fa[top[u]];
		} else {
			NodeSeg ans=query(1,1,n,id[top[v]],id[v]);
			res2=comb(ans,res2);
			// printf("%d %d ",id[top[v]],id[v]);
			// ans.print();
			// res2.print();
			v=Fa[top[v]];
		}
	}
	if(id[u]>id[v]){
		int t=u;
		u=v, v=t;
		NodeSeg tmp=res1;
		res1=res2;
		res2=tmp;
	}
	res1=comb(res1,query(1,1,n,id[u],id[v]));
	res=comb(res1,res2);
	return res.val;
}
int main(){
// 	freopen("test.in","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",col+i);
	for(int i=1;i<n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		adde(u,v); adde(v,u);
	}
	dfs1(1,0);
	cnt=0;
	dfs2(1,1);
	// for(int i=1;i<=n;++i)
	// 	printf("%d ",id[i]);
	// puts("");
	build(1,1,n);
	while(m--){
		char op=getchar();
		if(op=='C'){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			modify(u,v,w);
		}
		else if(op=='Q'){
			int u,v;
			scanf("%d%d",&u,&v);
			printf("%d\n",path_col(u,v));
		}
		else ++m;
	}
	return 0;
}
2024/6/18 15:45
加载中...