社区讨论

六年级女生,CSP-J在即,求一道初赛阅读程序题

学术版参与者 6已保存回复 23

讨论操作

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

当前回复
23 条
当前快照
1 份
快照标识符
@mhj9y0ol
此快照首次捕获于
2025/11/03 23:07
4 个月前
此快照最后确认于
2025/11/04 06:02
4 个月前
查看原帖
问题:第 11 行两个整数 n mn\ m,代表城市个数和操作数。
22 行至第 nn 行,每行两个整数 u vu\ v,代表城市 uu 和城市 vv 之间有一条路。
n+1n+1 行,有 nn 个整数,第 ii 个代表第 ii 个点的初始防御值 valival_i
n+2n+2 行一个整数 idid,代表初始的首都为 idid
n+3n+3 行至第 n+m+2n+m+2 行,首先有一个整数 optopt
如果 opt=1opt=1,接下来有一个整数 idid,代表把首都修改为 idid
如果 opt=2opt=2,接下来有三个整数 x y vx\ y\ v,代表将 x yx\ y 路径上的所有城市的防御值修改为 vv
如果 opt=3opt=3,接下来有一个整数 idid,代表询问以城市 idid 为根的子树中的最小防御值。
CPP
#include <bits/stdc++.h>
#define ls(u) u*2
#define rs(u) u*2+1
using namespace std;
namespace zxy{
	const int N=1e5+5;
	int h[N],dfn,num[N],f[N],top[N],rt,n,val[N],in_num[N],m,dep[N],siz[N],id,cnt;
	struct edge{
		int from,to,nxt;
	}g[N];
	void add(int u,int v){
		g[++cnt].from=u;
		g[cnt].to=v;
		g[cnt].nxt=h[u];
		h[u]=cnt;
	}
	void dfs1(int u,int fa){
		f[u]=fa;dep[u]=dep[f[u]]+1;siz[u]=1;
		for(int i=h[u];~i;i=g[i].nxt){
			int v=g[i].to;
			if(v==fa)continue;
			dfs1(v,u);siz[u]+=siz[v];
		}
	}
	void dfs2(int u,int fa){
		num[u]=++dfn;int pos=0,maxn=-1;in_num[dfn]=u;
		for(int i=h[u];~i;i=g[i].nxt){
			int v=g[i].to;
			if(v==fa)continue;
			if(siz[v]>maxn) pos=v,maxn=siz[v];
		}top[pos]=top[u];if(pos!=0)dfs2(pos,u);
		for(int i=h[u];~i;i=g[i].nxt){
			int v=g[i].to;
			if(v==fa||v==pos)continue;
			top[v]=v;dfs2(v,u);
		}
	}
	struct tree{
		int l,r,min,lz;
	}t[N<<2];
	void build(int u,int l,int r){
		t[u].l=l,t[u].r=r;
		
		if(l==r){
			t[u].min=val[in_num[l]];return ;
		}
		int mid=(l+r)/2;
		build(ls(u),l,mid);build(rs(u),mid+1,r);
		t[u].min=min(t[ls(u)].min,t[rs(u)].min);
	}
	void push_down(int u){
		int ad=t[u].lz;t[u].lz=0;
		t[ls(u)].min=ad;t[rs(u)].min=ad;
		t[ls(u)].lz=ad;t[rs(u)].lz=ad;
	}
	void cover(int u,int l,int r,int x){
		if(t[u].r<l||t[u].l>r){
			return ;
		}
		if(t[u].l>=l&&t[u].r<=r){
			t[u].min=x;t[u].lz=x;
			return ;
		}
		if(t[u].lz!=0)push_down(u);
		cover(ls(u),l,r,x);cover(rs(u),l,r,x);
		t[u].min=min(t[ls(u)].min,t[rs(u)].min);
	}
	int query(int u,int l,int r){
		if(t[u].r<l||t[u].l>r){
			return 2147483647;
		}if(t[u].l>=l&&t[u].r<=r){
			return t[u].min;
		}push_down(u);
		return min(query(ls(u),l,r),query(rs(u),l,r));
	}
	void cover_chain(int x,int y,int z){
		while(top[x]!=top[y]){
			if(dep[x]<dep[y])swap(x,y);
			cover(1,num[top[x]],num[x],z);
			x=f[top[x]];
		}if(dep[x]<dep[y])swap(x,y);
		cover(1,num[y],num[x],z);
	}
	int query_tree(int u){
		if(u==rt) return t[1].min;
		if(num[rt]>num[u]&&num[rt]<num[u]+siz[u]){
			int x=rt;
			while(f[x]!=u){
				x=f[x];
			}
			return min(query(1,1,num[x]-1),query(1,num[x]+siz[x],n));
		}else{
			return query(1,num[u],num[u]+siz[u]-1);
		}
	}
	void print_tree(int u){
		printf("%d:%d %d %d\n",u,t[u].l,t[u].r,t[u].min);
		if(t[u].l==t[u].r) return ;
		print_tree(ls(u));print_tree(rs(u));
	}
	int main(){
		memset(h,-1,sizeof(h));
		scanf("%d%d",&n,&m);
		for(int i=1;i<n;i++){
			int u,v;scanf("%d%d",&u,&v);
			add(u,v);add(v,u);
		}
		for(int i=1;i<=n;i++){
			scanf("%d",&val[i]);
		}scanf("%d",&id);rt=id;top[1]=1;
		dfs1(1,0);dfs2(1,0);build(1,1,n);
//		for(int i=1;i<=n;i++){
//				printf("%d ",top[i]);
//		}printf("\n");	
		while(m--){
			int opt;
			scanf("%d",&opt);
			if(opt==1){
				scanf("%d",&rt);
			}if(opt==2){
				int x,y,z;scanf("%d%d%d",&x,&y,&z);
				cover_chain(x,y,z);
			}if(opt==3){
				int u;scanf("%d",&u);
//				print_tree(1);
				printf("%d\n",query_tree(u));
			}
//			print_tree(1);
		}
		return 0;
	}
}
int main(){
	zxy::main();return 0;
}
/*5 7
1 2
1 3
3 4
3 5
1 2 3 4 5
1
3 1
2 3 4 6
3 2
2 2 3 5
3 3
2 3 3 4
3 4*/
请指出程序的错误

回复

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

正在加载回复...