树链剖分/dfs序


  树上单点修改+子树修改+链查询

  其实用dfs序做也可以……

  其实树链剖分就是一个特殊的dfs序嘛= =所以树链剖分也可以搞子树~(Orz ZYF)

  至于为什么……你看在做剖分的时候不也是dfs下去的?然后只不过是先走重儿子,但本质上也是一个dfs序,所以dfs序能搞的子树操作,链剖也是兹瓷的~

  然后随便水水就过了……

  WA了一发:查询从x到1的权值和的时候,写成了while(top[x]),改成while(x)后就过了……

  1. /**************************************************************
  2. Problem: 4034
  3. User: Tunix
  4. Language: C++
  5. Result: Accepted
  6. Time:2192 ms
  7. Memory:27956 kb
  8. ****************************************************************/
  9.  
  10. //BZOJ 4034
  11. #include<vector>
  12. #include<cstdio>
  13. #include<cstring>
  14. #include<cstdlib>
  15. #include<iostream>
  16. #include<algorithm>
  17. #define rep(i,n) for(int i=0;i<n;++i)
  18. #define F(i,j,n) for(int i=j;i<=n;++i)
  19. #define D(i,j,n) for(int i=j;i>=n;--i)
  20. #define pb push_back
  21. using namespace std;
  22. inline int getint(){
  23. int v=,sign=; char ch=getchar();
  24. while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
  25. while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
  26. return v*sign;
  27. }
  28. const int N=2e5+,INF=~0u>>;
  29. typedef long long LL;
  30. /******************tamplate*********************/
  31.  
  32. int to[N<<],nxt[N<<],head[N],cnt;
  33. void add(int x,int y){
  34. to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
  35. to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt;
  36. }
  37. LL n,m,a[N];
  38. LL sm[N<<],ad[N<<];
  39. #define mid (l+r>>1)
  40. #define L (o<<1)
  41. #define R (o<<1|1)
  42. inline void maintain(int o,int l,int r){
  43. sm[o]=sm[L]+sm[R];
  44. }
  45. inline void Push_down(int o,int l,int r){
  46. if (ad[o]) {
  47. ad[L]+=ad[o]; sm[L]+=ad[o]*(mid-l+);
  48. ad[R]+=ad[o]; sm[R]+=ad[o]*(r-mid);
  49. ad[o]=;
  50. }
  51. }
  52. void update(int o,int l,int r,int ql,int qr,LL v){
  53. if (ql<=l && qr>=r) sm[o]+=v*(LL)(r-l+),ad[o]+=v;
  54. else{
  55. Push_down(o,l,r);
  56. if (ql<=mid) update(L,l,mid,ql,qr,v);
  57. if (qr>mid) update(R,mid+,r,ql,qr,v);
  58. maintain(o,l,r);
  59. }
  60. }
  61. LL query_it(int o,int l,int r,int ql,int qr){
  62. if (ql<=l && qr>=r) return sm[o];
  63. else{
  64. LL ans=; Push_down(o,l,r);
  65. if (ql<=mid) ans+=query_it(L,l,mid,ql,qr);
  66. if (qr>mid) ans+=query_it(R,mid+,r,ql,qr);
  67. return ans;
  68. }
  69. }
  70.  
  71. int top[N],fa[N],dep[N],tid[N],st[N],ed[N],son[N],size[N];
  72. void dfs(int x){
  73. size[x]=; son[x]=;
  74. int mx=;
  75. for(int i=head[x];i;i=nxt[i])
  76. if (to[i]!=fa[x]){
  77. fa[to[i]]=x;
  78. dep[to[i]]=dep[x]+;
  79. dfs(to[i]);
  80. size[x]+=size[to[i]];
  81. if (size[to[i]]>mx) mx=size[to[i]],son[x]=to[i];
  82. }
  83. }
  84. int tot;
  85. bool vis[N];
  86. void connect(int x,int f){
  87. vis[x]=;
  88. top[x]=f;
  89. st[x]=tid[x]=++tot;
  90. if (son[x]) connect(son[x],f);
  91. for(int i=head[x];i;i=nxt[i])
  92. if (!vis[to[i]])
  93. connect(to[i],to[i]);
  94. ed[x]=tot;
  95. }
  96. LL query(int x){
  97. LL ans=;
  98. while(x){
  99. ans+=query_it(,,n,tid[top[x]],tid[x]);
  100. x=fa[top[x]];
  101. }
  102. return ans;
  103. }
  104. int main(){
  105. #ifndef ONLINE_JUDGE
  106. freopen("4034.in","r",stdin);
  107. freopen("4034.out","w",stdout);
  108. #endif
  109. n=getint(); m=getint();
  110. F(i,,n) a[i]=getint();
  111. F(i,,n){
  112. int x=getint(),y=getint();
  113. add(x,y);
  114. }
  115. dfs();
  116. connect(,);
  117. F(i,,n) update(,,n,tid[i],tid[i],a[i]);
  118. int cmd,x,y;
  119. F(i,,m){
  120. cmd=getint(); x=getint();
  121. if (cmd==){
  122. y=getint();
  123. update(,,n,tid[x],tid[x],y);
  124. }else if (cmd==){
  125. y=getint();
  126. update(,,n,st[x],ed[x],y);
  127. }else{
  128. printf("%lld\n",query(x));
  129. }
  130. }
  131. return ;
  132. }

4034: [HAOI2015]T2

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 265  Solved: 113
[Submit][Status][Discuss]

Description

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

Input

第一行包含两个整数 N, M 。表示点数和操作数。

接下来一行 N 个整数,表示树中节点的初始权值。
接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

Output

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

Sample Input

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

Sample Output

6
9
13

HINT

对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

会超过 10^6 。

Source

[Submit][Status][Discuss]

【BZOJ】【4034】【HAOI2015】T2的更多相关文章

  1. 【BZOJ 2754 喵星球上的点名】

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2512  Solved: 1092[Submit][Status][Discuss] Descript ...

  2. 【BZOJ】【3083】遥远的国度

    树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...

  3. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  4. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  5. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  6. 【BZOJ】【1025】【SCOI2009】游戏

    DP/整数拆分 整个映射关系可以分解成几个循环(置换群的预备知识?),那么总行数就等于各个循环长度的最小公倍数+1(因为有个第一行的1~N).那么有多少种可能的排数就等于问有多少种可能的最小公倍数. ...

  7. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...

  8. 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

  9. 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...

  10. 【BZOJ】【2434】【NOI2011】阿狸的打字机

    AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...

随机推荐

  1. 利用js的for循环实现一个简单的“九九乘法表”

    For循环九九乘法表 for循环是javascript中一种常用的循环语句,可以很好的解决在程序中需要重复执行某些语句,利用for循环实现简单的“九九乘法表”的效果: 让循环从小到大,依次排序,并计算 ...

  2. mysql连接查询经典小例题

    mysql连接查询: Mysql连接查询支持多表连接 对同一张表可以重复连接多次(别名在多次连接同一张表时很重要) 例题1: 下面有2张表 teams表 比赛结果表:result 问题: 得出一张表: ...

  3. C++求最小公倍数

    题目内容:求两个正整数的最小公倍数. 输入描述:输入数据含有不多于50对的数据,每对数据由两个正整数(0<n1,n2<100000)组成. 输出描述:对于每组数据n1和n2,计算最小公倍数 ...

  4. Microsoft Visual C++ Runtime error解决方法

    1: 当出现下图时提示Microsoft Visual C++ Runtime error 2:此时不要关闭该对话框,然后打开任务管理器(Ctrl+Shift+Esc)如下图: 找到Microsoft ...

  5. udev/raw/asmlib/多路径 配置asm

    asmlib 是linux上面给磁盘/分区头上面打上asm的标记,供asm使用,而且当磁盘的盘符发生改变的时候,不会影响到asm disk,从效果上说,和udev没有本质区别,在redhat 4和5中 ...

  6. SRF之数据字典

      框架提供数据字典的配置和显示的功能 字典以编码作为标识,用varchar(50)类型保存字典的编码.   字典的用法 1.在代码里边需要查询字典信息的 可用 Components.DataDict ...

  7. WPF数据双向绑定

    设置双向绑定,首先控件要绑定的对象要先继承一个接口: INotifyPropertyChanged 然后对应被绑定的属性增加代码如下: 意思就是当Age这个属性变化时,要通知监听它变化的人. 即:Pr ...

  8. IOS笔记 : addChildViewController

    一下addChildViewController,一个ViewController可以添加多个子ViewController,但是这 些子ViewController只有一个是显示到父视图中的,可以通 ...

  9. [转载]--Ubuntu下修改DNS重启也能用的方法

    安装好Ubuntu之后设置了静态IP地址,再重启后就无法解析域名.想重新设置一下DNS,打开/etc/resolv.conf cat /etc/resolv.conf# Dynamic resolv. ...

  10. Android:简单实现ViewPager+TabHost+TabWidget实现导航栏导航和滑动切换

    viewPager是v4包里的一个组件,可以实现滑动显示多个界面. android也为viewPager提供了一个adapter,此adapter最少要重写4个方法: public int getCo ...