社区讨论
六年级女生,CSP-J在即,求一道初赛阅读程序题
学术版参与者 6已保存回复 23
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 23 条
- 当前快照
- 1 份
- 快照标识符
- @mhj9y0ol
- 此快照首次捕获于
- 2025/11/03 23:07 4 个月前
- 此快照最后确认于
- 2025/11/04 06:02 4 个月前
问题:第 行两个整数 ,代表城市个数和操作数。
第 行至第 行,每行两个整数 ,代表城市 和城市 之间有一条路。
第 行,有 个整数,第 个代表第 个点的初始防御值 。
第 行一个整数 ,代表初始的首都为 。
第 行至第 行,首先有一个整数 。
如果 ,接下来有一个整数 ,代表把首都修改为 ;
如果 ,接下来有三个整数 ,代表将 路径上的所有城市的防御值修改为 ;
如果 ,接下来有一个整数 ,代表询问以城市 为根的子树中的最小防御值。
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 条回复,欢迎继续交流。
正在加载回复...