MnZn求助树链剖分,过样例全WA,悬赏关注
查看原帖
MnZn求助树链剖分,过样例全WA,悬赏关注
569484
ProzacPainkiller楼主2023/1/14 10:22
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+1;
int n,q,dep[N],siz[N],f[N],top[N],hson[N],num[N],val[N],tot;
vector<int> g[N];
void dfs1(int x)
{
	siz[x]=1;
	for(int v:g[x])
	{
		if(v==f[x])	continue;
		dep[v]=dep[x]+1;
		f[v]=x;
		dfs1(v);
		siz[x]+=siz[v];
		if(siz[v]>siz[hson[x]])	hson[x]=v;
	}
}
void dfs2(int x,int tp)
{
	top[x]=tp;
	num[x]=++tot;
	if(hson[x])	dfs2(hson[x],tp);
	for(int v:g[x])
	{
		if(v==f[x]||v==hson[x])	continue;
		dfs2(v,v);
	}
}
struct Node
{
	int sm,mx;
	Node()
	{
		mx=-30000;
	}
}st[N<<2];
void update(int o,int pos,int x,int l,int r)
{
	if(l>r)	return;
	st[o].mx=max(st[o].mx,val[pos]);
	st[o].sm+=x;
	if(l==r)	return;
	int mid=l+r>>1;
	if(pos<=mid)	update(o<<1,pos,x,l,mid);
	else	update((o<<1)+1,pos,x,mid+1,r);
}
int query(int op,int o,int l,int r,int ql,int qr)
{
	if(l>=ql&&r<=qr)
	{
		if(!op)	return st[o].mx;
		return st[o].sm;
	}
	int mid=l+r>>1,ret=op?0:-30000;
	if(ql<=mid)	ret=query(op,o<<1,l,mid,ql,qr);
	if(mid<qr)
	{
		if(!op)	ret=max(ret,query(0,(o<<1)+1,mid+1,r,ql,qr));
		else	ret+=query(0,(o<<1)+1,mid+1,r,ql,qr);
	}
	return ret;
}
int tquery(int op,int u,int v)
{
	int ans=op?0:-30000;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]>dep[top[v]])
		{
			if(op)	ans+=query(1,1,1,n,num[top[u]],num[u]);
			else	ans=max(ans,query(0,1,1,n,num[top[u]],num[u]));
			u=f[top[u]];
		}
		else
		{
			if(op)	ans+=query(1,1,1,n,num[top[v]],num[v]);
			else	ans=max(ans,query(0,1,1,n,num[top[v]],num[v]));
			v=f[top[v]];
		}
	}
	if(dep[u]>dep[v])
	{
		if(op)	ans+=query(1,1,1,n,num[v],num[u]);
		else	ans=max(ans,query(0,1,1,n,num[v],num[u]));
	}
	else
	{
		if(op)	ans+=query(1,1,1,n,num[u],num[v]);
		else	ans=max(ans,query(0,1,1,n,num[u],num[v]));
	}
	return ans;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1,a,b;i<n;i++)
	{
		cin>>a>>b;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	dep[1]=1;
	f[1]=1;
	dfs1(1);
	dfs2(1,1);
	for(int i=1;i<=n;i++)
	{
		cin>>val[i];
		update(1,num[i],val[i],1,n);
	}
	cin>>q;
	char op[8];
	for(int i=0,a,b;i<q;i++)
	{
		cin>>op>>a>>b;
		if(op[1]=='H')
		{
			int x=b-val[a];
			val[a]=b;
			update(1,num[a],x,1,n);
		}
		else if(op[1]=='M')	cout<<tquery(0,a,b)<<'\n';
		else	cout<<tquery(1,a,b)<<'\n';
	}
	return 0;
}
2023/1/14 10:22
加载中...