传送门

解题思路

树链剖分裸题,线段树维护。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define int long long
  5. using namespace std;
  6. const int MAXN = 100005;
  7. inline int rd(){
  8. int x=0,f=1;char ch=getchar();
  9. while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
  10. while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  11. return f?x:-x;
  12. }
  13. int n,m,a[MAXN],sum[MAXN<<2],lazy[MAXN<<2];
  14. int w[MAXN],id[MAXN],fa[MAXN],dep[MAXN],son[MAXN],siz[MAXN],top[MAXN];
  15. int num,head[MAXN],cnt,to[MAXN<<1],nxt[MAXN<<1];
  16. inline void add(int bg,int ed){
  17. to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
  18. }
  19. void dfs1(int x,int f,int d){
  20. dep[x]=d,fa[x]=f,siz[x]=1;
  21. int maxson=-1;
  22. for(register int i=head[x];i;i=nxt[i]){
  23. int u=to[i];if(u==f) continue;
  24. dfs1(u,x,d+1);
  25. siz[x]+=siz[u];
  26. if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
  27. }
  28. }
  29. void dfs2(int x,int topf){
  30. id[x]=++num,w[num]=a[x],top[x]=topf;
  31. if(!son[x]) return;
  32. dfs2(son[x],topf);
  33. for(register int i=head[x];i;i=nxt[i]){
  34. int u=to[i];if(u==fa[x] || u==son[x]) continue;
  35. dfs2(u,u);
  36. }
  37. }
  38. //----------------------xds------------------------
  39. inline void pushdown(int x,int ln,int rn){
  40. sum[x<<1]+=ln*lazy[x],sum[x<<1|1]+=rn*lazy[x];
  41. lazy[x<<1]+=lazy[x],lazy[x<<1|1]+=lazy[x];
  42. lazy[x]=0;
  43. }
  44. void build(int x,int l,int r){
  45. if(l==r){
  46. sum[x]=w[l];
  47. return;
  48. }
  49. int mid=l+r>>1;
  50. build(x<<1,l,mid);
  51. build(x<<1|1,mid+1,r);
  52. sum[x]=sum[x<<1]+sum[x<<1|1];
  53. }
  54. void update(int x,int l,int r,int L,int R,int k){
  55. if(L<=l && r<=R){
  56. sum[x]+=(r-l+1)*k;
  57. lazy[x]+=k;
  58. return;
  59. }
  60. int mid=l+r>>1;
  61. if(lazy[x]) pushdown(x,mid-l+1,r-mid);
  62. if(mid>=L) update(x<<1,l,mid,L,R,k);
  63. if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
  64. sum[x]=sum[x<<1]+sum[x<<1|1];
  65. }
  66. int query(int x,int l,int r,int L,int R){
  67. if(L<=l && r<=R) return sum[x];
  68. int mid=l+r>>1,ret=0;
  69. if(lazy[x]) pushdown(x,mid-l+1,r-mid);
  70. if(mid>=L) ret+=query(x<<1,l,mid,L,R);
  71. if(mid<R) ret+=query(x<<1|1,mid+1,r,L,R);
  72. return ret;
  73. }
  74. int qSon(int x){
  75. int ret=0;
  76. while(top[x]!=1){
  77. ret+=query(1,1,n,id[top[x]],id[x]);
  78. x=fa[top[x]];
  79. }
  80. ret+=query(1,1,n,1,id[x]);
  81. return ret;
  82. }
  83. signed main(){
  84. n=rd(),m=rd();
  85. for(register int i=1;i<=n;i++) a[i]=rd();
  86. int op,x,y,z;
  87. for(register int i=1;i<n;i++){
  88. x=rd(),y=rd();
  89. add(x,y),add(y,x);
  90. }
  91. dfs1(1,0,1),dfs2(1,1);
  92. // for(register int i=1;i<=n;i++) cout<<id[i]<<" ";cout<<endl;
  93. build(1,1,n);
  94. while(m--){
  95. op=rd();
  96. if(op==1){
  97. x=rd(),z=rd();
  98. update(1,1,n,id[x],id[x],z);
  99. }
  100. else if(op==2){
  101. x=rd(),z=rd();
  102. update(1,1,n,id[x],id[x]+siz[x]-1,z);
  103. }
  104. else {
  105. int x=rd();
  106. printf("%lld\n",qSon(x));
  107. }
  108. }
  109. return 0;
  110. }

LUOGU P3178 [HAOI2015]树上操作的更多相关文章

  1. 【luogu P3178 [HAOI2015]树上操作】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3178 模板题 菜 #include <cstdio> #include <cstring& ...

  2. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  3. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 思路 板子嘛,其实我感觉树剖没啥脑子 就是debug 代码 #include <bits/stdc++.h> #define int long l ...

  4. 洛谷P3178 [HAOI2015]树上操作 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P3178 这道题目是一道树链剖分的模板题. 但是在解决这道问题的同事刷新了我的两个认识: 第一个认识是:树链剖分不光可以处理链, ...

  5. 洛谷——P3178 [HAOI2015]树上操作

    https://www.luogu.org/problem/show?pid=3178#sub 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 ...

  6. 洛谷P3178 [HAOI2015]树上操作

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  7. 洛谷P3178 [HAOI2015]树上操作(线段树)

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  8. 洛谷 P3178 [HAOI2015]树上操作

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  9. P3178 [HAOI2015]树上操作 树链剖分

    这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...

随机推荐

  1. Linq Lambda 中group by多列后count数量的写法

    直接上代码: List<Student> ss = new List<Student>(); Student ss1 = , Age = , Name = " }; ...

  2. 建立ftp服务器和客户端

    参考:https://www.cnblogs.com/judes/p/9546447.html 补充: 权限设置:如下所示,如果需要上传文件需要勾选write权限,需要在文件中添加内容勾选append ...

  3. Date、DateFormat、Calendar、System、Math类总结

    java.util.Date: 构造方法 public Date() 空参构造,返回当前时间 public Date(long 毫秒值) 指定毫秒值的时间 普通方法 long getTime() 获取 ...

  4. vagrant生成多台虚拟机

    第一种: # -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2 ...

  5. JS流程控制语句 多种选择(Switch语句) 当有很多种选项的时候,switch比if else使用更方便。

    多种选择(Switch语句) 当有很多种选项的时候,switch比if else使用更方便. 语法: switch(表达式) { case值1: 执行代码块 1 break; case值2: 执行代码 ...

  6. 如何将存储在MongoDB数据库中的数据导出到Excel中?

    将MongoDB数据库中的数据导出到Excel中,只需以下几个步骤: (1)首先,打开MongoDB安装目录下的bin文件夹,(C:\Program Files (x86)\MongoDB\Serve ...

  7. 看 《android权威编程指南》 的笔记

    Android 编译工具 确保ant已安装并正常运行,android sdk的tools/和platform-tools目录包含在可执行文件的搜索路径中 切换到项目目录并执行以下命令: android ...

  8. AM历史消息及文件记录删除

    1.下载 folderclear.bat 文件 2.用编辑方式打开这个文件 3.对里面的参数做修改 4.这个批处理文件,保留了 完整的一个月的消息记录 (如 今天是 2017.3.15 ,那么 清除数 ...

  9. IPMI 远程配置

    #重启ipmi服务 #重启ipmi服务 #将 channel 1 设置为静态 IP #设置 IP #设置 channel 1 掩码 #设置 channel 1 网关 #查看用户名及 ID #设置ID号 ...

  10. Java驼峰和下划线互相转化

    直接上代码 : package com.utils; public class ChangeChar { public static final char UNDERLINE = '_'; publi ...