社区讨论

萌新求助!!救救新人吧

P2486[SDOI2011] 染色参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi7pc1vb
此快照首次捕获于
2025/11/21 01:25
4 个月前
此快照最后确认于
2025/11/21 01:25
4 个月前
查看原帖
搞了好久,样例没过QAQ
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
	char chr=getchar();	int f=1,ans=0;
	while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
	while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
	return ans*f;
}void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}const int M=100005;
int n,T,a[100005],head[M<<1],nxt[M<<1],ver[M<<1],tot,fa[M],son[M],dep[M],sz[M],dfn[M],top[M],b[M],ret,pos1,pos2,tl[M<<2],tr[M<<2],val[M<<2],ll[M<<2],rr[M<<2],sum[M<<2],lz[M<<2];
inline void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void dfs1(int x,int y){
	sz[x]=1;dep[x]=dep[y]+1;fa[x]=y;
	for(int i=head[x];i;i=nxt[i]){
		if(ver[i]==y) continue;
		dfs1(ver[i],x);
		sz[x]+=sz[ver[i]];
		if(sz[ver[i]]>sz[son[x]]) son[x]=ver[i];
	}
}int t,lc,rc;
void dfs2(int x,int topf){
	dfn[x]=++t;top[x]=topf;a[t]=b[x];
	if(!son[x]) return;else dfs2(son[x],topf);
	for(int i=head[x];i;i=nxt[i]){
		if(dfn[ver[i]]) continue;
		dfs2(ver[i],ver[i]);
	}
}
#define ls (i<<1)
#define rs (i<<1|1)
#define mid (l+r>>1)
inline void Push_Up(int i){
	sum[i]=sum[ls]+sum[rs];
	if(ll[rs]==rr[ls]) --sum[i];
	ll[i]=ll[ls];rr[i]=rr[rs];
}
inline void Push_Down(int i){
	if(!lz[i]) return;
	lz[ls]=lz[rs]=ll[ls]=ll[rs]=rr[ls]=rr[rs]=lz[i];
	sum[ls]=sum[rs]=1;
	lz[i]=0;
}
void Build(int i,int l,int r){
	tl[i]=l,tr[i]=r;
	if(l==r){ll[i]=rr[i]=val[i]=a[l];sum[i]=1;return;}
	Build(ls,l,mid),Build(rs,mid+1,r);
	Push_Up(i);
}
void Update(int i,int l,int r,int ql,int qr,int x){
	if(ql<=l&&r<=qr){ll[i]=rr[i]=val[i]=x;sum[i]=1;lz[i]=x;return;}
	Push_Down(i);
	if(ql<=mid) Update(ls,l,mid,ql,qr,x);
	if(qr>mid)  Update(rs,mid+1,r,ql,qr,x);
	Push_Up(i);
}
int Query(int i,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) {if(l==qr) lc=ll[i];if(r==qr) rc=rr[i];return sum[i];}
	Push_Down(i);int ans=0;
	if(qr<=mid) return Query(ls,l,mid,ql,qr);
	if(ql>mid)  return Query(rs,mid+1,r,ql,qr);
	ans=Query(ls,l,mid,ql,qr)+Query(rs,mid+1,r,ql,qr);
	if(rr[ls]==ll[rs]) --ans;
	Push_Up(i);
	return ans;
}
inline void Tree_Add(int u,int v,int c){
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        Update(1,1,n,dfn[top[u]],dfn[u],c);
        u=fa[top[u]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    Update(1,1,n,dfn[u],dfn[v],c);
}
inline void Tree_Ask(int u,int v){
    ret=0,pos1=0,pos2=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v),swap(pos1,pos2);   
        ret+=Query(1,1,n,dfn[top[u]],dfn[u]);
        if(rc==pos1) --ret;
        pos1=lc,u=fa[top[u]];
    }
    if(dfn[u]>dfn[v]) swap(u,v),swap(pos1,pos2);
    ret+=Query(1,1,n,dfn[u],dfn[v]);
    if(lc==pos1) --ret;if(rc==pos2) --ret; 
    write(ret),puts("");
}
int main(){
	n=read(),T=read();
	for(int i=1;i<=n;i++) b[i]=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read();
		add(x,y),add(y,x);
	}dfs1(1,0);dfs2(1,1);Build(1,1,n);
	while(T--){char opt[2],x,y,z;
		scanf("%s ",opt);
		x=read(),y=read();
		if(opt[0]=='Q') Tree_Ask(x,y);
		else z=read(),Tree_Add(x,y,z);
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...