传送门

树链剖分固然可以搞。

但还有另一种做法,可以看出,增加一个节点的权值会对以它为根的整棵子树都有影响,相当于给整棵子树增加一个值。

而给以某一节点 x 为根的子树增加一个权值也会影响当前子树,节点 y 所增加的值为 dis[y] * z - (dis[x] - 1) * z,每个节点都会增加 -(dis[x] - 1) * z ,

询问时只用加上 dis[y] * y 和当前节点 y 的权值。

给整棵子树增加一个权值可以用 dfs 序 + 线段树搞, dis 数组可以预处理出来。

——代码

 #include <cstdio>
#include <cstring>
#define LL long long
#define root 1, 1, n
#define ls now << 1, l, mid
#define rs now << 1 | 1, mid + 1, r using namespace std; const int MAXN = ;
int n, m, cnt, tot;
int head[MAXN], next[MAXN << ], to[MAXN << ], tid[MAXN], size[MAXN];
LL a[MAXN << ], b[MAXN << ], val[MAXN], dis[MAXN]; inline void add(int x, int y)
{
to[cnt] = y;
next[cnt] = head[x];
head[x] = cnt++;
} inline void dfs(int u)
{
int i, v;
tid[u] = ++tot;
size[u] = ;
for(i = head[u]; i != -; i = next[i])
{
v = to[i];
if(!size[v])
{
dis[v] = dis[u] + ;
dfs(v);
size[u] += size[v];
}
}
} inline void push_down(int now)
{
a[now << ] += a[now];
a[now << | ] += a[now];
b[now << ] += b[now];
b[now << | ] += b[now];
a[now] = b[now] = ;
} inline void update(LL x, LL y, int ql, int qr, int now, int l, int r)
{
if(ql <= l && r <= qr)
{
a[now] += x;
b[now] += y;
return;
}
push_down(now);
int mid = (l + r) >> ;
if(ql <= mid) update(x, y, ql, qr, ls);
if(mid < qr) update(x, y, ql, qr, rs);
} inline LL query(int u, int x, int now, int l, int r)
{
if(l == r) return dis[u] * a[now] + b[now];
push_down(now);
int mid = (l + r) >> ;
if(x <= mid) return query(u, x, ls);
else return query(u, x, rs);
} int main()
{
int i, x, z;
LL y;
scanf("%d %d", &n, &m);
for(i = ; i <= n; i++) scanf("%lld", &val[i]);
memset(head, -, sizeof(head));
for(i = ; i < n; i++)
{
scanf("%d %d", &x, &y);
add(x, y);
add(y, x);
}
dis[] = ;
dfs();
for(i = ; i <= n; i++) update(, val[i], tid[i], tid[i] + size[i] - , root);
for(i = ; i <= m; i++)
{
scanf("%d %d", &z, &x);
if(z == )
{
scanf("%lld", &y);
update(, y, tid[x], tid[x] + size[x] - , root);
}
else if(z == )
{
scanf("%lld", &y);
update(y, -((dis[x] - ) * y), tid[x], tid[x] + size[x] - , root);
}
else printf("%lld\n", query(x, tid[x], root));
}
return ;
}

最新文章

  1. SVNKit支持SSH连接
  2. 上网八个常用cmd命令你掌握了几个?
  3. 一些pc端web事件移动端不再可行
  4. Opencv出现错误“0xc000007b”的解决办法
  5. js的小随笔
  6. 从Wireshark监听的数据中提取需要的数据
  7. ZSDRM001-发货清单
  8. 去掉url后面的#
  9. What is a heap?--reference
  10. Struts2方法调用的三种方式
  11. java.lang.OutOfMemoryError: unable to create new native thread(转)
  12. java中拼接两个数组
  13. sql发邮件
  14. Html网页的代码
  15. htm5
  16. MPLS VPN随堂笔记1
  17. ArcGIS JS Api 4.x修改三维球背景技巧
  18. 后台List里的数据传到前台表格和下拉列表为什么不显示
  19. springboot使用hibernate validator校验,Bean Validation校验
  20. python的__mro__与__slot__

热门文章

  1. php的iconv函数中utf8与utf-8的差异
  2. ping localhost出现地址::1
  3. Apache Cordova
  4. 获取一段HTML文本中的第一张图片与截取内容摘要
  5. 关于重置功能(type=&quot;reset&quot;)的相关问题
  6. Android性能分析工具Profile GPU rendering详细介绍
  7. DoveCLL and Resistance(湖北省赛)
  8. Report Builder 打开报错
  9. WebGL 绘制Line的bug(二)
  10. [Java]Java工程师成神之路