同一数据点在本地评测过,可在洛谷上WA
  • 板块P3950 部落冲突
  • 楼主Eraine
  • 当前回复7
  • 已保存回复7
  • 发布时间2022/12/28 12:02
  • 上次更新2023/10/24 06:20:48
查看原帖
同一数据点在本地评测过,可在洛谷上WA
305891
Eraine楼主2022/12/28 12:02

rt,#1在本地过,在洛谷上显示第9行输出 “Yes”

思路大致是这样,边树链剖分,每条边权值0/1表示有没有战争,把路径上所有的权值或后1输出“No”,0输出“Yes”

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define lc tr[i].ch[0] 
#define rc tr[i].ch[1]
#define mid (l+r)/2
using namespace std;
const int N=3e5;
vector<int>E[N+5];
int dep[N+5],sz[N+5],son[N+5],fa[N+5];
void dfs1(int u,int f){
	dep[u]=dep[f]+1;
	sz[u]=1;
	fa[u]=f;
	for(int i=0;i<E[u].size();i++){
		int v=E[u][i];
		if(v==f)
			continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]])
			son[u]=v;
	}
}
int id[N+5],rev[N+5],top[N+5],tot;
void dfs2(int u,int t){
	id[u]=++tot;
	rev[tot]=u;
	top[u]=t;
	if(!son[u])
		return;
	dfs2(son[u],t);
	for(int i=0;i<E[u].size();i++){
		int v=E[u][i];
		if(v==son[u]||v==fa[u])
			continue;
		dfs2(v,v);
	}
}
struct segTree{
	int ch[2];
	bool sum;
}tr[4*N+5];
int cnt,root;
void pushup(int i){
	tr[i].sum=tr[lc].sum|tr[rc].sum;
}
void build(int &i,int l,int r){
	i=++cnt;
	if(l==r){
		tr[i].sum=0;
		return;
	}
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(i);
}
void update(int i,int l,int r,int x,int val){
	if(l==r){
		tr[i].sum=val;
		return;
	}
	if(x<=mid)
		update(lc,l,mid,x,val);
	else
		update(rc,mid+1,r,x,val);
	pushup(i);
}
bool query(int i,int l,int r,int L,int R){
	if(L<=l&&R>=r)
		return tr[i].sum;
	bool res=0;
	if(L<=mid)
		res|=query(lc,l,mid,L,R);
	if(R>mid)
		res|=query(rc,mid+1,r,L,R);
	return res;
}
int n;
bool queryQuery(int u,int v){
	bool res=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])
			swap(u,v);
		res|=query(root,1,n,id[top[u]],id[u]);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])
		swap(u,v);
	if(u!=v)
		res|=query(root,1,n,id[u]+1,id[v]);
	return res;
}
void queryChange(int x){
	update(root,1,n,id[x],1);
}
void queryEnd(int x){
	update(root,1,n,id[x],0);
}
int rec[N+5];
int main(){
	//freopen("travian.in","r",stdin);
	//freopen("travian.out","w",stdout);
	int m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(root,1,n);
	int sum=0;
	for(int i=1;i<=m;i++){
		char opt=getchar();
		opt=getchar();
		int p,q,x;
		switch(opt){
			case 'Q':
				scanf("%d%d",&p,&q);
				if(queryQuery(p,q))
					printf("No\n");
				else
					printf("Yes\n");
				break;
			case 'C':
				scanf("%d%d",&p,&q);
				if(dep[p]>dep[q])
					x=p;
				else
					x=q;
				queryChange(x);
				rec[++sum]=x;
				break;
			case 'U':
				scanf("%d",&x);
				x=rec[x];
				queryEnd(x);
				break;
		}
	}
	return 0;
}
2022/12/28 12:02
加载中...