玄关
  • 板块学术版
  • 楼主Mustard_Zjld
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/17 15:52
  • 上次更新2024/8/17 18:42:39
查看原帖
玄关
550588
Mustard_Zjld楼主2024/8/17 15:52

给一棵有根树,这棵树由编号为1~n的n个结点组成。根结点的编号为R。每个结点都有一个权值,结点i的权值为vi。 接下来有M组操作,操作分为两类: 1 a x,表示将结点a的子树上所有结点的权值增加x; 2 a,表示求结点a的子树上所有结点的权值之和。


第一行有三个整数n, m和R。 第二行有n个整数,第i个整数表示vi。 在接下来的n-1行中,每行两个整数,表示一条边。 在接下来的m行中,每行一组操作。


对于每组2 a操作,输出一个整数,表示[以结点a为根的子树]上所有结点的权值之和。

样例

dfs序+线段数组,代码有误求调。

#include<bits/stdc++.h>
using namespace std;
int n,m,root,v[1000005],tot,head[1000005],Next[2000005],vet[2000005],tst,in[1000005],out[1000005];
long long c[1000005];
void add(int a,int b)
{
	Next[++tot]=head[a];
	vet[tot]=b;
	head[a]=tot;
	return;
}
int lowbit(int x)
{
	return x&-x;
}
void pushup(int x,int y,int f)
{
	for(int i=head[x];i;i=Next[i])
	{
		int j=vet[i];
		if(j==f)
			continue;
		pushup(j,y,x);
	}
	for(int i=x;i<=n;i+=lowbit(i))
		c[i]+=y;
	return;
}
long long sum(int x)
{
	long long r=0;
	for(int i=x;i;i-=i&-i)
		r+=c[i];
	return r;
}
void dfs(int now,int fa)
{
	in[now]=++tst;
	pushup(tst,v[now],tst);
	for(int i=head[now];i;i=Next[i])
	{
		int j=vet[i];
		if(j==fa)
			continue;
		dfs(j,now);
	}
	out[now]=tst;
	return;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>root;
	for(int i=1;i<=n;i++)
		cin>>v[i];
	for(int i=1;i<=n-1;i++)
	{
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dfs(root,0);
	for(int i=1;i<=m;i++)
	{
		int op,x,y;
		cin>>op>>x;
		if(op==1)
		{
			cin>>y;
			pushup(in[x],y,in[x]);
		}
		else
		{
			int l=in[x],r=out[x];
			cout<<sum(r)-sum(l-1)<<'\n';
		}
	}
	return 0;
}
2024/8/17 15:52
加载中...