树剖20分求助,改了一上午
查看原帖
树剖20分求助,改了一上午
127812
wycha楼主2022/10/1 12:27

如题,看讨论区从0分改到20分,实在找不出问题了

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define il inline
#define gtc getchar()
#define ptc(x) putchar(x)
#define rdi read1()
#define rdl read2()
il int read1(){re int x=0;re bool f=0;re char c=gtc;while(c<'0'||c>'9'){if(c=='-')f=1;c=gtc;}while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gtc;return f?-x:x;}
il ll read2(){re ll x=0;re bool f=0;re char c=gtc;while(c<'0'||c>'9'){if(c=='-')f=1;c=gtc;}while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gtc;return f?-x:x;}
il void wti(re int x){if(x>9) wti(x/10);ptc(x%10+48);}
il void wtl(ll x){if(x>9) wtl(x/10);ptc(x%10+48);}
il void wrt(ll x){if(x<0)ptc('-'),x=-x;if(x>2147483647) wtl(x);else wti(x);}
il char gts(){re char c=gtc,x;while(c<'A'||c>'Z') c=gtc;c=gtc,x=gtc;while(x>='A'&&x<='Z') x=gtc;return c;}
il ll max(ll x,ll y){if(x>y) return x;return y;}
//以上为快读快输,输入输出换成cin/cout还是20分,快读快输应该没有问题

const int N=30010;
#define add(x,y) to[++tot]=y,nt[tot]=head[x],head[x]=tot
int head[N],to[N<<1],nt[N<<1],tot;
int v[N];
int n;

int dep[N];
int ch[N];
int fa[N];
int hson[N];
int dfn[N];
int top[N];
int rk[N];
int dim;
il void dfs1(re int o){
	ch[o]=1;
	dep[o]=dep[fa[o]]+1;
	for(re int i=head[o],v=to[i];i;i=nt[i],v=to[i]){
		if(v==fa[o]) continue;
		fa[v]=o;
		dfs1(v);
		ch[o]+=ch[v];
		if(ch[hson[o]]<ch[v]) hson[o]=v;
	}
}
il void dfs2(re int o,re int tp){
	top[o]=tp;
	dfn[o]=++dim;
	rk[dim]=o;
	if(hson[o]) dfs2(hson[o],tp);
	for(re int i=head[o],v=to[i];i;i=nt[i],v=to[i]){
		if(v==hson[o]||v==fa[o]) continue;
		dfs2(v,v);
	}
}

int t[N<<2],mx[N<<2],num[N<<2];
il void pushup(re int o){
	mx[o]=max(mx[o<<1],mx[o<<1|1]);
	num[o]=num[o<<1]+num[o<<1|1];
}
il void build(re int o,re int l,re int r){
	if(r<=l){mx[o]=num[o]=v[rk[l]];return;}
	re int m=l+r>>1;
	build(o<<1,l,m);
	build(o<<1|1,m+1,r);
	pushup(o);
}
il int qnum(re int o,re int l,re int r,re int x,re int y){
	if(x<=l&&y>=r) return num[o];
	re int res=0;
	re int m=l+r>>1;
	if(x<=m) res+=qnum(o<<1,l,m,x,y);
	if(y>m) res+=qnum(o<<1|1,m+1,r,x,y);
	return res;
}
il int qmax(re int o,re int l,re int r,re int x,re int y){
	if(x<=l&&y>=r) return mx[o];
	re int m=l+r>>1;
	re int res=-1e9;
	if(x<=m) res=max(res,qmax(o<<1,l,m,x,y));
	if(y>m) res=max(res,qmax(o<<1|1,m+1,r,x,y));
	return res;
}
il void upd(re int o,re int l,re int r,re int x,re int k){
	if(r<=l){num[o]=mx[o]=k;return;}
	re int m=l+r>>1;
	if(x<=m) upd(o<<1,l,m,x,k);
	if(x>m) upd(o<<1|1,m+1,r,x,k);
	pushup(o);
}

il int qmx(re int x,re int y){
	re int res=-1e9;
	while(top[x]!=top[y]){
		if(dep[top[x]]>dep[top[y]]) res=max(res,qmax(1,1,n,dfn[top[x]],dfn[x])),x=fa[top[x]];
		else res=max(res,qmax(1,1,n,dfn[top[y]],dfn[y])),y=fa[top[y]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	return max(res,qmax(1,1,n,dfn[x],dfn[y]));
}

il int qnm(re int x,re int y){
	re int res=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]>dep[top[y]]) res+=qnum(1,1,n,dfn[top[x]],dfn[x]),x=fa[top[x]];
		else res+=qmax(1,1,n,dfn[top[y]],dfn[y]),y=fa[top[y]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	return res+qnum(1,1,n,dfn[x],dfn[y]);
}

signed main(){
	
	n=rdi;
	for(re int i=1;i<n;i++){
		re int u=rdi,v=rdi;
		add(u,v),add(v,u);
	}
	for(re int i=1;i<=n;i++) v[i]=rdi;
	
	dfs1(1);
	dfs2(1,1);
	build(1,1,n);
	
	re int q=rdi;
	while(q--){
		re char c=gts();
		re int x=rdi,y=rdi;
		if(c=='M') wrt(qmx(x,y)),puts("");
		if(c=='S') wrt(qnm(x,y)),puts("");
		if(c=='H') upd(1,1,n,dfn[x],y);
	}
	
	return 0;
}
2022/10/1 12:27
加载中...