求调(树剖+线段树)
查看原帖
求调(树剖+线段树)
1049442
OIerror楼主2024/9/3 22:32
#include<cstdio>
#include<cmath>
#include<iostream>
#include<vector>
using namespace std;
int n,m;
vector<int>g[100001];
int a[100001];
int father[100001],dep[100001],wc[100001],sz[100001],dfn[100001],rdfn[100001],top[100001],vistime=0;
long long lzy[400001],w[400001];
void dfs1(int u,int f)
{
	dep[u]=dep[f]+1;
	father[u]=f;
	sz[u]=1;
	for(int i=0; i<g[u].size(); i++)
	{
		int v=g[u][i];
		if(v!=f)
		{
			dfs1(v,u);
			sz[u]+=sz[v];
			if(sz[v]>sz[wc[u]])
			{
				wc[u]=v;
			}
		}
	}
}
void dfs2(int u,int Top)
{
	vistime++;
	dfn[u]=vistime;
	rdfn[vistime]=u;
	top[u]=Top;
	if(wc[u]!=0)
	{
		dfs2(wc[u],Top);
		for(int i=0; i<g[u].size(); i++)
		{
			int v=g[u][i];
			if(v!=father[u]&&v!=wc[u])
			{
				dfs2(v,v);
			}
		}
	}
}
void pushup(int u)
{
	w[u]=w[u*2]+w[u*2+1];
}
void maketag(int u,int len,long long x)
{
	lzy[u]+=x;
	w[u]+=len*x;
}
void pushdown(int u,int l,int r)
{
	int mid=(l+r)/2;
	maketag(u*2,mid-l+1,lzy[u]);
	maketag(u*2+1,r-mid,lzy[u]);
	lzy[u]=0;
}
bool inrange(int l,int r,int L,int R)
{
	return (L<=l)&&(r<=R);
}
bool outrange(int l,int r,int L,int R)
{
	return (r<L)||(R<l);
}
void build(int u,int l,int r)
{
	if(l==r)
	{
		w[u]=a[rdfn[l]];
		return;
	}
	int mid=(l+r)/2;
	build(u*2,l,mid);
	build(u*2+1,mid+1,r);
	pushup(u);
}
void update_1(int u,int l,int r,int pos,int x)
{
	if(l==r)
	{
		w[u]+=x;
		return;
	}
	int mid=(l+r)/2;
	if(pos<=mid)
	{
		update_1(u*2,l,mid,pos,x);
	}
	else
	{
		update_1(u*2+1,mid+1,r,pos,x);
	}
	pushup(u);
}
void update_2(int u,int l,int r,int L,int R,int x)
{
	if(inrange(l,r,L,R))
	{
		maketag(u,r-l+1,1ll*x);
	}
	else if(!outrange(l,r,L,R))
	{
		int mid=(l+r)/2;
		pushdown(u,l,r);
		update_2(u*2,l,mid,L,R,x);
		update_2(u*2+1,mid+1,r,L,R,x);
		pushup(u);
	}
}
long long query(int u,int l,int r,int L,int R)
{
	if(inrange(l,r,L,R))
	{
		return w[u];
	}
	else if(!outrange(l,r,L,R))
	{
		int mid=(l+r)/2;
		pushdown(u,l,r);
		return query(u*2,l,mid,L,R)+query(u*2+1,mid+1,r,L,R);
	}
	else
	{
		return 0;
	}
}
long long ask(int x)
{
	long long ans=0;
	while(top[x]!=1)
	{
		ans+=query(1,1,n,dfn[top[x]],dfn[x]);
		x=father[top[x]];
	}
	ans+=query(1,1,n,1,dfn[x]);
	return ans;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1; i<=n-1; i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1; i<=m; i++)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int x,a;
			scanf("%d%d",&x,&a);
			update_1(1,1,n,dfn[x],a);
		}
		else if(op==2)
		{
			int x,a;
			scanf("%d%d",&x,&a);
			update_2(1,1,n,dfn[x],dfn[x]+sz[x]-1,a);
		}
		else
		{
			int x;
			scanf("%d",&x);
			printf("%lld\n",ask(x));
		}
	}
	return 0;
}
2024/9/3 22:32
加载中...