社区讨论

树剖90分求条 第二个测试点WA了呜呜呜

P3979遥远的国度参与者 5已保存回复 10

讨论操作

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

当前回复
10 条
当前快照
1 份
快照标识符
@lo2mbxx5
此快照首次捕获于
2023/10/23 16:11
2 年前
此快照最后确认于
2023/10/23 16:11
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
#define lid root<<1
#define rid root<<1|1
const int N=1000114;
using namespace std;
inline int read(){
	int f(1),x(0);
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
	return f*x;
}
inline void write(int x){
	if(x<0) putchar('-') ,x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
struct tree{
	int l,r,min,lazy;
	inline void update(int w){
		min=w;	
		lazy=w;
		return ;
	}
} t[N<<2];

int head[N<<1],nxt[N<<1],to[N<<1],val[N],tot(0),n,m,cap,in[N],out[N],cnt(0);
int dfn[N],f[N],top[N],siz[N],son[N],rk[N],rks[N],num(0);
inline void add(int x,int y){
	to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
	return ;
}

inline void dfs1(int now,int fa){
	f[now]=fa;
	siz[now]=1;
	in[now]=++cnt;
	for(register int i=head[now];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		dfs1(y,now);
		siz[now]+=siz[y];
		if(siz[son[now]]<siz[y]){
			son[now]=y;
		}
	}
	out[now]=cnt;
}
inline void dfs2(int now,int topp){
	top[now]=topp;
	dfn[now]=++num;
	rk[num]=now;
	if(son[now]) {
		dfs2(son[now],topp);
	}
	for(register int i=head[now];i;i=nxt[i]){
		int y=to[i];
		if(y==f[now]||y==son[now]) continue;
		dfs2(y,y);
	}
}

inline void pushdown(int root){
	if(!t[root].lazy) return ;
	t[lid].update(t[root].lazy);
	t[rid].update(t[root].lazy);
	t[root].lazy=0;
	return ;
}
inline void pushup(int root){
	t[root].min=min(t[lid].min,t[rid].min);
	return ;
} 
inline void rangeupdate(int root,int l,int r,int w){
	if(l<=t[root].l&&r>=t[root].r){
		t[root].update(w);
		return ;
	}
	pushdown(root);
	int mid=(t[root].l+t[root].r)>>1;
	if(l<=mid) rangeupdate(lid,l,r,w);
	if(r>mid) rangeupdate(rid,l,r,w);
	pushup(root);
}
inline void build(int root,int l,int r){ 
	t[root].l=l,t[root].r=r; 
	t[root].min=t[root].lazy=0;
	if(l==r) { 
		t[root].min=val[rk[l]]; 
		return ; 
	} 
	
	int mid=(l+r)>>1;
	build(lid,l,mid);
	build(rid,mid+1,r);
	pushup(root);
}

inline int askmin(int root,int l,int r){
	if(l<=t[root].l&&r>=t[root].r) {
		return t[root].min;
	}
	int mid=(t[root].l+t[root].r)>>1,minx=INT_MAX;
	if(l<=mid) minx=min(minx,askmin(lid,l,r));
	if(r>mid) minx=min(minx,askmin(rid,l,r));
	return minx;
}

inline void qchange(int x,int y,int w){
	while(top[x]!=top[y]){
		if(dfn[top[x]]<dfn[top[y]]){
			swap(x,y);
		}
		rangeupdate(1,dfn[top[x]],dfn[x],w);
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y]){
		swap(x,y);
	}
	rangeupdate(1,dfn[x],dfn[y],w);
	return ;
}

signed main(void){
	n=read(),m=read();
	for(register int i=1;i<n;i++){
		register int asd=read(),jkl=read();
		add(asd,jkl),add(jkl,asd);
	}
	for(register int i=1;i<=n;i++){
		val[i]=read();
	}
	
	cap=read();
	
	dfs1(1,0),dfs2(1,1),build(1,1,n);
	for(register int i=1;i<=cnt;i++){
		in[i]=dfn[i];
		out[i]=dfn[i]+siz[i]-1;
	}
	while(m--){
		register int opt=read();
		if(opt==1){
			cap=read();
		}
		else if(opt==2){
			register int xx=read(),yy=read(),zz=read();
			qchange(xx,yy,zz);
		}
		else if(opt==3){
			//////////////////////////////////////////////////////////////////
			int a=read();
			if(a==cap){
				write(askmin(1,1,n)),putchar('\n');
			}
			else if(in[a]<=in[cap]&&out[a]>=out[cap]){
				int l,r;
				for(int i=head[a];i;i=nxt[i]){
					int y=to[i];
					if(in[y]<=in[cap]&&out[y]>=out[cap]){
						l=in[y];r=out[y];
					 	break;
					}
				} 	
				write(min(askmin(1,1,l-1),askmin(1,r+1,n))),putchar('\n');
			}
			else {
				write(askmin(1,in[a],out[a])),putchar('\n');
			}
			//////////////////////////////////////////////////////////////////
		}
	}
	
	return 0;
}
求神教我

回复

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

正在加载回复...