BZOJ4034-[HAOI2015]树上操作

版权声明:不念过去,不畏未来,一切都是过眼云烟。 https://blog.csdn.net/qq_34531807/article/details/83590501

题解:
一道模板题。
树链剖分+线段树。
码农题。
写得心态爆炸。
纪念一下。
C o d e Code:

#include<bits/stdc++.h>
#define ll long long
const int N=1e5+5;
using namespace std;
int n,m,head[N*2],a[N],size[N],son[N],tot,fi[N],en[N];
int belong[N],cnt,fa[N],b[N];
long long tree[N*4],add[N*4];
inline int read()
{
	int x=0,f=1;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
struct node
{
	int vet,next;
}edge[N*2];
void Add(int u,int v)
{
	edge[++tot].vet=v;
	edge[tot].next=head[u];
	head[u]=tot;
}
void pushdown(int o,int l,int r)
{
	int mid=(l+r)>>1;
	if(add[o])
	{
		add[o<<1]+=add[o];
		add[o<<1|1]+=add[o];
		tree[o<<1]+=(long long)(mid-l+1)*add[o];
		tree[o<<1|1]+=(long long)(r-mid)*add[o];
		add[o]=0;
	}
}
void dfs1(int u,int father)
{
	size[u]=1;
	int mx=0;
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].vet;
		if(v!=father)
		{
			fa[v]=u;
			dfs1(v,u);
			size[u]+=size[v];
			if(size[v]>mx)
			{
				mx=size[v];
				son[u]=v;
			}
		}
	}
}
void dfs2(int u,int top)
{
	belong[u]=top;
	fi[u]=++cnt;b[cnt]=u;
	if(son[u])dfs2(son[u],top);
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].vet;
		if(v!=fa[u]&&v!=son[u])dfs2(v,v);
	}
	en[u]=cnt;
}
void build(int o,int l,int r)
{
	if(l==r)
	{
		tree[o]=a[b[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	tree[o]=tree[o<<1]+tree[o<<1|1];
}
void update(int o,int l,int r,int x,int y,int t)
{
	if(l>y||r<x)return;
	if(l>=x&&r<=y)
	{
		add[o]+=t;
		tree[o]+=(long long)(r-l+1)*t;
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	update(o<<1,l,mid,x,y,t);
	update(o<<1|1,mid+1,r,x,y,t);
	tree[o]=tree[o<<1]+tree[o<<1|1];
}
long long query(int o,int l,int r,int x,int y)
{
	if(l>y||r<x)return 0;
	if(l>=x&&r<=y)return tree[o];
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	return query(o<<1,l,mid,x,y)+query(o<<1|1,mid+1,r,x,y);
}
long long queryans(int x)
{
	long long ans=0;
	while(belong[x]!=1)
	{
		ans+=query(1,1,n,fi[belong[x]],fi[x]);
		x=fa[belong[x]];
	}
	ans+=query(1,1,n,1,fi[x]);
	return ans;
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		Add(u,v);Add(v,u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	while(m--)
	{
		int id=read();
		if(id==1)
		{
			int x=read(),y=read();
			update(1,1,n,fi[x],fi[x],y);
		}else
		if(id==2)
		{
			int x=read(),y=read();
			update(1,1,n,fi[x],en[x],y);
		}else
		{
			int x=read();
			printf("%lld\n",queryans(x));
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34531807/article/details/83590501