树的点权
问题描述
给定一棵有n个点的树(点的编号为1~n),根为1,点有点权,设点i的初始值为0,给出q个操作,每个操作给出两个点和一个值,u,v,t,表示将u到v的路径上的所有点加t,输出所有操作后每个点的点权,。
输入格式
第一行输入两个整数n,q表示树的点的数目与操作次数
下面n-1行,每行两个整数x,y表示边的信息
下面q行,每行三个整数u,v,t表示将u到v的路径上的所有点加t
输出格式
n行,每行表示点i的权值
样例
in
5 5
1 2
1 3
2 4
2 5
1 5 1
2 5 10
3 4 3
2 4 4
1 2 4
out
8
22
3
7
11
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct node{
int to;
int nxt;
}E[maxn<<1];
int h[maxn],w[maxn],dep[maxn],f[maxn][25],lg[maxn],etot;
void addedge(int x,int y)
{
E[++etot].to=y;
E[etot].nxt=h[x];
h[x]=etot;
}
void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
f[u][0]=fa;
for (int i=1;(1<<i)<=dep[u];i++)
{
f[u][i]=f[f[u][i-1]][i-1];
}
for (int i=h[u];i;i=E[i].nxt)
{
int v=E[i].to;
if (v!=fa)
{
dfs(v,u);
}
}
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
while(d)
{
int k=lg[d];
x=f[x][k];
d=d-(1<<k);
}
if (x==y) return x;
for (int i=lg[dep[x]];i>=0;i--)
{
if (f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
void dfs1(int u,int f)
{
for (int i=h[u];i;i=E[i].nxt)
{
int v;
v=E[i].to;
if (v!=f)
{
dfs1(v,u);
w[u]+=w[v];
}
}
}
int main()
{
int n,q;
cin>>n>>q;
for (int i=1;i<n;i++)
{
int x,y;
cin>>x>>y;
addedge(x,y);
addedge(y,x);
}
dfs(1,0);
for (int i=1;i<=q;i++)
{
int x,y,t;
cin>>x>>y>>t;
int l=lca(x,y);
w[x]+=t;
w[y]+=t;
w[l]-=t;
w[f[l][0]]-=t;
}
dfs1(1,0);
for (int i=1;i<=n;i++)
{
cout<<w[i]<<endl;
}
}
浙公网安备 33010602011771号