新学树剖,WA20求助
查看原帖
新学树剖,WA20求助
305854
Drind楼主2023/5/27 07:55
#include<bits/stdc++.h>
using namespace std;

int tot,cnt,root=1;

struct node
{
	int to,nxt;
}edge[1000001];
int head[500001];
void add(int u,int v)
{
	edge[++cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}

int dep[500001];
int fa[500001];
int hson[500001];
int top[500001];
int idx[500001];
int siz[500001]; 
int rk[500001];

void dfs1(int u,int f)
{
	siz[u]=1;
	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(v==f)
			continue;
		dep[v]=dep[u]+1;
		fa[v]=u;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[hson[u]])
			hson[u]=v;
		
	}
}

void dfs2(int u,int t)
{
	top[u]=t;
	idx[u]=++tot;
	rk[tot]=u;
	if(!hson[u])
		return;
	dfs2(hson[u],t);
	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(v!=fa[u]&&v!=hson[u])
			dfs2(v,v);
	}
}

int a[500001];

struct segtree
{
	int l,r,w,siz,mx;
}tree[1000001];

void pushup(int x)
{
	tree[x].w=tree[x*2].w+tree[x*2+1].w;
	tree[x].mx=max(tree[x*2].mx,tree[x*2+1].mx);
}

void build(int id,int l,int r)
{
	tree[id].l=l;
	tree[id].r=r;
	tree[id].siz=r-l+1;
	if(l==r)
	{
		tree[id].w=tree[id].mx=a[rk[l]];
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	pushup(id);
}

void upd(int id,int l,int r,int q,int val)
{
	if(l==r)
	{
		tree[id].w=tree[id].mx=val;
		return;
	}
	int mid=(l+r)/2;
	if(q<=mid)
		upd(id*2,l,mid,q,val);
	else
		upd(id*2+1,mid+1,r,q,val);
	pushup(id);
}

int Isum(int id,int l,int r)
{
	int ans=0;
	if(l<=tree[id].l&&r>=tree[id].r)
	{
		return tree[id].w;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(l<=mid)
		ans+=Isum(id*2,l,r);
	if(r>mid)
		ans+=Isum(id*2+1,l,r);
	return ans;
}

int Imax(int id,int l,int r)
{
	int ans=-1e9;
	if(l<=tree[id].l&&r>=tree[id].r)
	{
		return tree[id].mx;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(l<=mid)
		ans=max(ans,Imax(id*2,l,r));
	if(r>mid)
		ans=max(ans,Imax(id*2+1,l,r));
	return ans;
}

int Isum_ultra(int x,int y)//两点之间求和
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		ans+=Isum(root,idx[x],idx[top[x]]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	ans+=Isum(root,idx[x],idx[y]);
	return ans;
}

int Imax_ultra(int x,int y)//两点之间求最大值
{
	int ans=-1e9;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		ans=max(ans,Imax(root,idx[x],idx[top[x]]));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	ans=max(ans,Imax(root,idx[x],idx[y]));
	return ans;
}

int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	int q;
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		string opt;
		int u,v;
		cin>>opt>>u>>v;
		if(opt[1]=='H')
		{
			upd(root,1,n,idx[u],v);
		}
		if(opt[1]=='S')
		{
			cout<<Isum_ultra(u,v)<<endl;
		}
		if(opt[1]=='M')
		{
			cout<<Imax_ultra(u,v)<<endl; 
		}
	}
}
2023/5/27 07:55
加载中...