社区讨论

玄学,实在太玄学了

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

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lo7yqsok
此快照首次捕获于
2023/10/27 09:57
2 年前
此快照最后确认于
2023/10/27 09:57
2 年前
查看原帖
这道题不难,而且我错的很有特点……大佬都点进来了,花几分钟看看呗(我会很感谢您的
我错的地方全是因为错误输出了1
本地十万的数据拍过了
CPP
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0') {
		x=x*10+ch-48;
		ch=getchar();
	}
	return x*f;
}
struct node {
	int l,r,num;
};
const int N=5e5+5;
node a[N<<1];
int lz[N<<2];
int n,m;
int w[N],c[N];
int ver[N<<1],head[N],nxt[N<<1];
int CNT=1;
void add1(int u,int v) {
	ver[++CNT]=v;
	nxt[CNT]=head[u];
	head[u]=CNT;
}
int son[N],ff[N],dfn[N],dep[N],sz[N];
int lg[N],fa[N][22];
void dfs1(int t) {
	sz[t]=1;
	int mmax=0;
	for(int i=head[t]; i; i=nxt[i]) {
		int to=ver[i];
		if(to==fa[t][0]) continue;
		fa[to][0]=t;
		dep[to]=dep[t]+1;
		dfs1(to);
		sz[t]+=sz[to];
		if(sz[to]>mmax) {
			mmax=sz[to];
			son[t]=to;
		}
	}
}
int cnt;
void dfs2(int t,int top) {
	dfn[t]=++cnt;
	ff[t]=top;
	c[cnt]=w[t];
	if(son[t]) dfs2(son[t],top);
	for(int i=head[t]; i; i=nxt[i]) {
		int to=ver[i];
		if(to==fa[t][0]||to==son[t]) continue;
		dfs2(to,to);
	}
}
void work() {
	for(int i=2; i<=n; ++i) lg[i]=lg[i/2]+1;
	for(int k=1; k<=lg[n]+1; ++k)
		for(int i=1; i<=n; ++i) fa[i][k]=fa[fa[i][k-1]][k-1];
}
int lca(int u,int v) {
	if(u==v) return u;
	if(dep[u]<dep[v]) swap(u,v);
	for(int k=lg[n]+1; k>=0; --k)
		if(dep[fa[u][k]]>=dep[v]) u=fa[u][k];
	if(u==v) return u;
	for(int k=lg[n]+1; k>=0; --k)
		if(fa[u][k]!=fa[v][k]) u=fa[u][k],v=fa[v][k];
	return fa[u][0];
}
node merge(node x,node y) {
	if(x.r==y.l) return node {x.l,y.r,x.num+y.num-1};
	return node {x.l,y.r,x.num+y.num};
}
#define ls t<<1,l,mid
#define rs t<<1|1,mid+1,r
void pushdown(int t) {
	a[t<<1]=a[t<<1|1]=node {lz[t],lz[t],1};
	lz[t<<1]=lz[t];lz[t<<1|1]=lz[t];
	lz[t]=0;
}
void build(int t=1,int l=1,int r=n) {
	if(l==r) {
		a[t].l=a[t].r=c[l];
		a[t].num=1;
		return;
	}
	int mid=(l+r)>>1;
	build(ls);
	build(rs);
	a[t]=merge(a[t<<1],a[t<<1|1]);
}
node query(int L,int R,int t=1,int l=1,int r=n) {
	if(l>=L&&r<=R)
	{
		return a[t];
	} 
	int mid=(l+r)>>1;
	if(lz[t]) pushdown(t);
	if(L>mid) return query(L,R,rs);
	if(R<=mid) return query(L,R,ls);
	return merge(query(L,R,ls),query(L,R,rs));
}
void add(int L,int R,int val,int t=1,int l=1,int r=n) {
	if(L<=l&&r<=R) {
		a[t]=node {val,val,1};
		lz[t]=val;
		return;
	}
	if(lz[t])
	pushdown(t);
	int mid=(l+r)>>1;
	if(L<=mid) add(L,R,val,ls);
	if(mid<R) add(L,R,val,rs);
	a[t]=merge(a[t<<1],a[t<<1|1]);
}
void C(int t,int top,int val) {
	if(dep[top]>=dep[ff[t]]) {
		add(dfn[top],dfn[t],val);
		return;
	}
	add(dfn[ff[t]],dfn[t],val);
	C(fa[ff[t]][0],top,val);
}
node Q(int t,int top) {
	if(dep[top]>=dep[ff[t]])
	{
		node ret=query(dfn[top],dfn[t]);
		return ret;
	}
	node r=query(dfn[ff[t]],dfn[t]),l=Q(fa[ff[t]][0],top);
	return merge(l,r);
}/*
void dfs(int t)
{
	cout<<t<<endl;
	cout<<son[t]<<" "<<sz[t]<<" "<<dfn[t]<<" "<<ff[t]<<endl;
	for(int i=head[t];i;i=nxt[i])
	{
		if(ver[i]==fa[t][0]) continue;
		dfs(ver[i]);
	}
}*/
int main() {
//	freopen("in.in","r",stdin);
	n=read();
	m=read();
	for(int i=1; i<=n; ++i) w[i]=read();
	int u,v;
	for(int i=1; i<n; ++i) {
		u=read();
		v=read();
		add1(u,v);
		add1(v,u);
	}
	fa[1][0]=1;
	dep[1]=1;
	dfs1(1);
	dfs2(1,1);
	work();
	build();
	char opt;
	for(int i=1; i<=m; ++i) {
		cin>>opt>>u>>v;
		int lc=lca(u,v);
		if(opt=='C') {
			int k;
			cin>>k;
			C(u,lc,k);
			C(v,lc,k);
		}
		if(opt=='Q') {
			node ret=query(dfn[lc],dfn[lc]);
			int topu=u,topv=v;
			for(int k=lg[n]+1; k>=0; --k) if(dep[fa[topu][k]]>dep[lc]) topu=fa[topu][k];
			for(int k=lg[n]+1; k>=0; --k) if(dep[fa[topv][k]]>dep[lc]) topv=fa[topv][k];
			if(lc==u) {
				cout <<Q(v,u).num<<endl;
			}
			if(lc==v) {
				cout<<Q(u,v).num<<endl;
			}
			if(lc!=v&&lc!=u) {
				node l=Q(u,topu);
				swap(l.l,l.r);
				node r=Q(v,topv);
				//cout<<"lc:"<<ret.l<<" "<<ret.r<<" "<<ret.num<<endl;
				//	cout<<v<<" "<<topv<<endl;
				//	cout<<r.l<<" "<<r.r<<" "<<r.num<<endl;
				cout<<merge(merge(l,ret),r).num<<endl;
			}
		}
	}
	return 0;
}

回复

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

正在加载回复...