树剖求条,玄关
查看原帖
树剖求条,玄关
373530
Reply_楼主2024/9/15 08:17

rt

#include<bits/stdc++.h>
#define int long long
#define R register
#define F(i,a,b) for(int i = (a);i<=(b);i++)
using namespace std;
inline int read(){R int x=0,t=1;R char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*t;}
const int N=1e6+10;
int n,siz[N],fa[N],dep[N],m,w[N],wt[N],tot,son[N],id[N],top[N];
struct Node
{
	int l,r,sum,add;
}tr[4*N];
vector<int>g[N];
inline void push_up(int x)
{
	tr[x].sum=tr[x*2].sum+tr[x*2+1].sum;
	return;
}
inline void push_down(int x)
{
	if(!tr[x].add) return;
	tr[x*2].add+=tr[x].add;
	tr[x*2+1].add+=tr[x].add;
	tr[x*2].sum+=(tr[x*2].r-tr[x*2].l+1)*tr[x].add;
	tr[x*2+1].sum+=(tr[x*2+1].r-tr[x*2+1].l+1)*tr[x].add;
	tr[x].add=0;
	return;
}
void build(int x,int l,int r)
{
	tr[x].l=l,tr[x].r=r;
	if(tr[x].l==tr[x].r){
		tr[x].sum=wt[l];
		return;
	}
	int mid=l+r>>1;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	push_up(x);
	return;
}
void update(int x,int l,int r,int k)
{
//	cout << x << " " << l << " " << r << " " << k << '\n';
	if(tr[x].l>=l && tr[x].r<=r){
		tr[x].sum+=(r-l+1)*k;
		tr[x].add+=k;
		return;
	}
	push_down(x);
	int mid=tr[x].l+tr[x].r>>1;
	if(mid>=l) update(x*2,l,r,k);
	if(mid<r) update(x*2+1,l,r,k);
	push_up(x);
}
int query(int x,int l,int r)
{
	if(tr[x].l>=l && tr[x].r<=r){
		return tr[x].sum;
	}
	push_down(x);
	int mid=tr[x].l+tr[x].r>>1,ans=0;
	if(mid>=l) ans+=query(x*2,l,r);
	if(mid<r) ans+=query(x*2+1,l,r);
	push_up(x);
	return ans;
}
void dfs1(int u,int Fa)
{
	siz[u]=1;
	fa[u]=Fa;
	dep[u]=dep[Fa]+1;
	int maxn=-1;
	for(int i = 0;i<g[u].size();i++){
		int v=g[u][i];
		if(v==Fa) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(maxn<siz[v]) maxn=siz[v],son[u]=v;
	}
	return;
}
void dfs2(int u,int topf)
{
	id[u]=++tot;
	top[u]=topf;
	wt[tot]=w[u];
	if(!son[u]) return;
	dfs2(son[u],topf);
	for(int i = 0;i<g[u].size();i++){
		int v=g[u][i];
		if(id[v]) continue;
		dfs2(v,v);
	}
	return;
}
inline int qRange(int x,int y)
{
	int sum=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		sum+=query(1,id[top[x]],id[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	sum+=query(1,id[x],id[y]);
	return sum;
}
inline void upRange(int x,int y,int z)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,id[top[x]],id[x],z);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(1,id[x],id[y],z);
	return;
}
inline void upson(int u,int k)
{
	update(1,id[u],id[u]+siz[u]-1,k);
	return;
}
signed main()
{
	n=read(),m=read();
	F(i,1,n) w[i]=read();
	F(i,2,n){
		int ui=read(),vi=read();
		g[ui].push_back(vi);
		g[vi].push_back(ui);
	}
	dfs1(1,0);
	dfs2(1,1);
//	F(i,1,n) wt[id[i]]=w[i];
	build(1,1,n);
	for(int i = 1;i<=m;i++){
		int op=read();
		if(op==1){
			int x=read(),a=read();
			upRange(x,x,a);
		}
		else if(op==2){
			int x=read(),a=read();
			upson(x,a);
		}
		else if(op==3){
			int x=read();
			cout << qRange(1,x) << '\n';
		}
	}
	return 0;
}

2024/9/15 08:17
加载中...