树剖30pts,求助
查看原帖
树剖30pts,求助
215915
lOpzIth楼主2022/10/4 14:42
#include<bits/stdc++.h>
#define int long long
const int N=3e5+5;
struct node
{
	int maxx,sum,l,r;
}tree[4*N];
int cnt,n,q,fa[N],dep[N],siz[N],top[N],dfn[N],rnk[N],hson[N],vis[N],dat[N];
std::vector<int> Tree[N];
inline int read()
{
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		w=(w<<3)+(w<<1)+(ch-48);
		ch=getchar();
	}
	return w*f;
}

void dfs1(int p,int deep)
{
	dep[p]=deep;
	hson[p]=0;
	siz[p]=1;
	int Size=Tree[p].size();
	for(int i=0;i<Size;i++)
	{
		int to=Tree[p][i];
		if(!vis[to])
		{
			vis[to]=1;
			fa[to]=p;
			dfs1(to,deep+1);
			siz[p]+=siz[to];
			if(siz[hson[p]]<siz[to])
			{
				hson[p]=to;
			}
		}
	}
}

void dfs2(int p,int tot)
{
	cnt++;
	dfn[p]=cnt;
	rnk[cnt]=p;
	top[p]=tot;
	if(hson[p]!=0)
	{
		vis[hson[p]]=1;
		dfs2(hson[p],tot);
	}
	int Size=Tree[p].size();
	for(int i=0;i<Size;i++)
	{
		int to=Tree[p][i];
		if(to!=hson[p]&&!vis[to])
		{
			vis[to]=1;
			dfs2(to,to);
		}
	}
}

void Build(int p,int l,int r)
{
	tree[p].l=l;tree[p].r=r;
	if(l==r)
	{
		tree[p].maxx=tree[p].sum=dat[dfn[l]];
		return ;
	}
	int mid=(l+r)/2;
	Build(p*2,l,mid);
	Build(p*2+1,mid+1,r);
	tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
	tree[p].maxx=std::max(tree[p*2].maxx,tree[p*2+1].maxx);
}

void Init()
{
	int root=1;
	vis[root]=1;
	dfs1(root,1);
	memset(vis,0,sizeof(vis));
	vis[root]=1;
	dfs2(root,root);
	Build(1,1,n);
}

int AskSum(int p,int l,int r)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	{
		return tree[p].sum; 
	}
	int mid=(tree[p].l+tree[p].r)/2,res=0;
	if(l<=mid) res+=AskSum(p*2,l,r);
	if(r>=mid+1) res+=AskSum(p*2+1,l,r);
	return res;
}

int AskMax(int p,int l,int r)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	{
		return tree[p].maxx;
	}
	int mid=(tree[p].l+tree[p].r)/2,Max=-0x3f3f3f3f3f3f3f3f;
	if(l<=mid) Max=std::max(Max,AskMax(p*2,l,r));
	if(r>=mid+1) Max=std::max(Max,AskMax(p*2+1,l,r));
	return Max;
}

void Change(int p,int l,int x)
{
	if(tree[p].l==tree[p].r&&tree[p].l==l)
	{
		tree[p].sum+=x;
		tree[p].maxx+=x;
		return ;
	}
	int mid=(tree[p].l+tree[p].r)/2;
	if(l<=mid) Change(p*2,l,x);
	if(l>=mid+1) Change(p*2+1,l,x);
	tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
	tree[p].maxx=std::max(tree[p*2].maxx,tree[p*2+1].maxx);
}

int JumpLinkMax(int u,int v)
{
	int res=-0x3f3f3f3f3f3f3f3f;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
		res=std::max(res,AskMax(1,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) std::swap(u,v);
	res=std::max(res,AskMax(1,dfn[v],dfn[u]));
	return res;
}

int JumpLinkSum(int u,int v)
{
	int res=0;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
		res+=AskSum(1,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) std::swap(u,v);
	res+=AskSum(1,dfn[v],dfn[u]);
	return res;
}

void Query()
{
	q=read();
	for(int i=1;i<=q;i++)
	{
		char s[15];scanf("%s",s+1);
		if(s[1]=='C')
		{
			int u=read(),x=read();
			Change(1,dfn[u],x-dat[u]);// add one point change
			dat[u]=x;
		}
		if(s[1]=='Q'&&s[2]=='M')
		{
			int u=read(),v=read();
			printf("%lld\n",JumpLinkMax(u,v));
		}
		if(s[1]=='Q'&&s[2]=='S')
		{
			int u=read(),v=read();
			printf("%lld\n",JumpLinkSum(u,v));
		}
	}
}

void Input()
{
	n=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		Tree[u].push_back(v);
		Tree[v].push_back(u);
	}
	for(int i=1;i<=n;i++) dat[i]=read();
	Init();
	Query();
}

signed main()
{
	//freopen("1.in","r",stdin);
	//freopen("liu.out","w",stdout);
	Input();
	return 0;
}
2022/10/4 14:42
加载中...