[SDOI2011]染色

link

和NOI2021的轻重链那道题写法上几乎一样,可以看成是轻重链是这道题套了个外壳。这道题问法还更直接一点,除了维护的东西变成了不相同的相邻元素对的个数,其它的代码层面几乎是一样的。然而傻逼的我还是调了许久。一是树链剖分线段树的初值应该是对应id的值,二是edge数组应该开成两倍。我也不知道我为什么没写<<1。脑子已经不太正常了。

大数据下下来在本地跑会爆栈,吓得不轻(靠到底哪里RE了),所幸交上去过了。或许可以通过修改某些选项给予某些指令来解决,但我懒得学。

但考场上遇到咋办呢……

code

#include<bits/stdc++.h>
//#define zczc
const int N=100010;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline void swap(int &s1,int &s2){
	int s3=s1;s1=s2;s2=s3;return;
}

struct aa{
	int data,lc,rc;
};
inline aa operator +(aa s1,aa s2){
	return (aa){s1.data+s2.data+(s1.rc!=s2.lc&&s1.rc!=0&&s2.lc!=0),s1.lc,s2.rc};
}
inline void swap_aa(aa &s1,aa &s2){
	aa s3=s1;s1=s2;s2=s3;return;
}
inline void print(aa wh){
	printf("%d %d %d\n",wh.data,wh.lc,wh.rc);
}

int m,n,a[N],ff[N];

#define lc (wh<<1)
#define rc (wh<<1|1)
#define mid (t[wh].l+t[wh].r>>1)
struct node{
	int l,r,lazy;
	aa data;
}t[N<<2];
inline void pushup(int wh){
	t[wh].data=t[lc].data+t[rc].data;
}
inline void pushnow(int wh,int val){
	t[wh].lazy=val;
	t[wh].data=(aa){0,val,val};
}
inline void pushdown(int wh){
	if(t[wh].lazy){
		pushnow(lc,t[wh].lazy);
		pushnow(rc,t[wh].lazy);
		t[wh].lazy=0;
	}
}
void build(int wh,int l,int r){
	t[wh].l=l,t[wh].r=r;
	if(l==r){
		t[wh].data=(aa){0,ff[l],ff[l]};
		return;
	}
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(wh);return;
}
void change(int wh,int wl,int wr,int val){
	if(wl<=t[wh].l&&t[wh].r<=wr){
		pushnow(wh,val);return;
	}
	pushdown(wh);
	if(wl<=mid)change(lc,wl,wr,val);
	if(wr>mid)change(rc,wl,wr,val);
	pushup(wh);return;
}
aa work(int wh,int wl,int wr){
	if(wl<=t[wh].l&&t[wh].r<=wr){
		return t[wh].data;
	}
	pushdown(wh);
	if(wl<=mid&&wr>mid)return work(lc,wl,wr)+work(rc,wl,wr);
	if(wl<=mid)return work(lc,wl,wr);
	return work(rc,wl,wr);
}
#undef lc
#undef rc
#undef mid

struct edge{
	int t,next;
}e[N<<1];
int head[N],esum;
inline void add(int fr,int to){
	e[++esum]=(edge){to,head[fr]};head[fr]=esum;
}

int size[N],lg[N],nxt[N][25],son[N],d[N];
void dfs(int wh,int fa,int deep){
	d[wh]=deep;size[wh]=1;nxt[wh][0]=fa;
	for(int i=1;i<=lg[d[wh]];i++){
		nxt[wh][i]=nxt[nxt[wh][i-1]][i-1];
	}
	for(int i=head[wh],th;i;i=e[i].next){
		if((th=e[i].t)==fa)continue;
		dfs(th,wh,deep+1);size[wh]+=size[th];
		if(size[th]>size[son[wh]])son[wh]=th;
	}
}
inline int lca(int s1,int s2){
	if(d[s1]<d[s2])swap(s1,s2);
	for(int i=lg[d[s1]];i>=0;i--){
		if(d[nxt[s1][i]]>=d[s2])s1=nxt[s1][i];
	}
	if(s1==s2)return s1;
	for(int i=lg[d[s1]];i>=0;i--){
		if(nxt[s1][i]^nxt[s2][i]){
			s1=nxt[s1][i],s2=nxt[s2][i];
		}
	}
	return nxt[s1][0];
}

int cnt,id[N],top[N];
void dfs2(int wh,int fa,int ntop){
	top[wh]=ntop;id[wh]=++cnt;
	ff[cnt]=a[wh];
	if(son[wh])dfs2(son[wh],wh,ntop);
	for(int i=head[wh],th;i;i=e[i].next){
		if((th=e[i].t)==fa)continue;
		if(th==son[wh])continue;dfs2(th,wh,th);
	}
}

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	
	lg[0]=1;for(int i=1;i<N;i++)lg[i]=lg[i>>1]+1;
	read(m);read(n);int s1,s2,s3;
	for(int i=1;i<=m;i++)read(a[i]);
	for(int i=1;i<m;i++){
		read(s1);read(s2);
		add(s1,s2);add(s2,s1);
	}
	dfs(1,0,1);dfs2(1,0,1);
	build(1,1,m);char w[10];
	//for(int i=1;i<=m;i++)printf("c:%d\n",work(1,i,i).lc);
	while(n--){
		//printf("working\n");
		scanf("%s",w);read(s1);read(s2);
		if(w[0]=='Q'){
			aa an1=(aa){0,0,0};aa an2=an1;
			while(top[s1]^top[s2]){
				if(d[top[s1]]<d[top[s2]])swap(s1,s2),swap_aa(an1,an2);
				an1=work(1,id[top[s1]],id[s1])+an1;
				//printf("ss:%d\n",work(1,id[top[s1]],id[s1]).lc);
				//printf("%d %d %d %d %d\n",s1,s2,an1.data,an1.lc,an1.rc);
				//printf("%d %d:::\n",s1,s2);
				//print(an1);print(an2);
				s1=nxt[top[s1]][0];
			}
			if(d[s1]<d[s2])swap(s1,s2),swap_aa(an1,an2);
			//print(an1);
			an1=work(1,id[s2],id[s1])+an1;
			//print(work(1,id[s2],id[s1]));
			//print(an1);print(an2);
			printf("%d\n",an1.data+an2.data+(an1.lc!=an2.lc&&an1.lc!=0&&an2.lc!=0)+1);
		}
		else{
			read(s3);
			while(top[s1]^top[s2]){
				if(d[top[s1]]<d[top[s2]])swap(s1,s2);
				change(1,id[top[s1]],id[s1],s3);
				s1=nxt[top[s1]][0];
			}
			if(d[s1]<d[s2])swap(s1,s2);
			change(1,id[s2],id[s1],s3);
		}
	}
	
	return 0;
}
posted @ 2022-07-04 17:23  Feyn618  阅读(25)  评论(0编辑  收藏  举报