树剖板子题求调玄关!!!
查看原帖
树剖板子题求调玄关!!!
586905
Linge_Zzzz一辈子乐队楼主2023/10/30 22:14

萌新刚学树剖,30pts,看了讨论区,发现他们30pts出的错我都没出)

#include <bits/stdc++.h>
using namespace std;

const int N=3e4+10,INF=0x3f3f3f3f;

int n,w[N],q;

struct edge{
	int v,nxt;
}e[N*2];
int head[N],cnt=2;
void add(int u,int v){
	e[cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt++;
}

int siz[N],fa[N],son[N],dep[N];
int top[N],dfn[N],rnk[N],num=0;

void dfs1(int u,int fat){
	siz[u]=1;
	fa[u]=fat;
	dep[u]=dep[fat]+1;
	int mx=-1;
	for(int i=head[u];i;i=e[i].nxt){
		if(e[i].v!=fat){
			dfs1(e[i].v,u);
			siz[u]+=siz[e[i].v];
			if(siz[e[i].v]>mx){
				mx=siz[e[i].v];
				son[u]=e[i].v;
			}
		}
	}
}

void dfs2(int u,int topf){
	top[u]=topf;
	num++;
	dfn[u]=num;
	rnk[num]=u;
	if(!son[u])return;
	dfs2(son[u],topf);
	for(int i=head[i];i;i=e[i].nxt){
		if(!dfn[e[i].v])
			dfs2(e[i].v,e[i].v);
	}
}

struct node{
	int l,r;
	int sum,mx;
}t[N*4];

void SegPushup(int p){
	t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
	t[p].sum=t[p*2].sum+t[p*2+1].sum;
}

void SegBuild(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(l==r){
		t[p].sum=t[p].mx=w[rnk[l]];
		return;
	}
	int m=l+r>>1;
	SegBuild(p*2,l,m);
	SegBuild(p*2+1,m+1,r);
	SegPushup(p);
}

int SegQuerySum(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r)return t[p].sum;
	int m=t[p].l+t[p].r>>1,ans=0;
	if(l<=m)ans+=SegQuerySum(p*2,l,r);
	if(r>m)ans+=SegQuerySum(p*2+1,l,r);
	return ans; 
}

int SegQueryMax(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r)return t[p].mx;
	int m=t[p].l+t[p].r>>1,ans=-INF;
	if(l<=m)ans=max(ans,SegQueryMax(p*2,l,r));
	if(r>m)ans=max(ans,SegQueryMax(p*2+1,l,r));
	return ans;
}

void SegUpdate(int p,int pos,int val){
	if(t[p].l==pos&&t[p].r==pos){
		t[p].sum=t[p].mx=val;
		return;
	}
	int m=t[p].l+t[p].r>>1;
	if(pos<=m)SegUpdate(p*2,pos,val);
	if(pos>m)SegUpdate(p*2+1,pos,val);
	SegPushup(p);
}

void TreeUpdate(int u,int val){
	SegUpdate(1,dfn[u],val);
} 

int TreeQueryMax(int u,int v){
	int ans=-INF;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		ans=max(ans,SegQueryMax(1,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	ans=max(ans,SegQueryMax(1,dfn[u],dfn[v]));
	return ans;
}

int TreeQuerySum(int u,int v){
	int ans=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		ans+=SegQuerySum(1,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	ans+=SegQuerySum(1,dfn[u],dfn[v]);
	return ans;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<n;i++){
		int a,b;
		cin>>a>>b;
		add(a,b),add(b,a);
	}
	for(int i=1;i<=n;i++)cin>>w[i];
	dfs1(1,0);
	dfs2(1,1);
	SegBuild(1,1,n);
	cin>>q;
	while(q--){
		char s[10];
		int u,v;
		cin>>s>>u>>v;
		if(s[1]=='H')TreeUpdate(u,v);
		if(s[1]=='M')cout<<TreeQueryMax(u,v)<<'\n';
		if(s[1]=='S')cout<<TreeQuerySum(u,v)<<'\n';
	}
	return 0;
}
2023/10/30 22:14
加载中...