传送门:easy problem

题意给定一棵n个节点以1为根的树,初始每个节点的值为0,现在我们要在树上进行一些操作,操作有两种类型。

1 x val 表示对以x为根的子树的每个点进行加权操作(我们定义每个节点的深度为每个节点到根1的距离),如果 y是以x为根的子树中的点那么 y节点的权值增加 ((dep[y]-dep[x])%k+1)*val 其中dep[y]表示y节点的深度,k为一个常数(1<=k<=5)

2 x 查询当前x节点的权值。

分析:这题用树链剖分有点大材小用,直接一个dfs将每点遍历完又回到该点重新标号映射到线段树上,然后每修改该点及它的子节点时在线段树上操作。由题意可发现,每隔k个深度权值增加是一样的,而k又很小,因此用k棵线段树分别维护整段区间内深度模k的点余x(0<x<k)的点,然后修改区间时分别给区间内模k为0,1...k-1的点修改,也就是给k棵线段树进行区间修改。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <string>
  4. #include <cmath>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <cstdlib>
  9. #include <stack>
  10. #include <vector>
  11. #include <set>
  12. #include <map>
  13. #define LL long long
  14. #define mod 100000000
  15. #define inf 0x3f3f3f3f
  16. #define eps 1e-6
  17. #define N 50010
  18. #define FILL(a,b) (memset(a,b,sizeof(a)))
  19. #define lson l,m,rt<<1
  20. #define rson m+1,r,rt<<1|1
  21. #define PII pair<int,int>
  22. using namespace std;
  23. struct edge
  24. {
  25. int v,next;
  26. edge(){}
  27. edge(int v,int next):v(v),next(next){}
  28. }e[N];
  29. int head[N],vis[N],tot;
  30. int col[][N<<],num;
  31. int st[N],ed[N],dep[N];
  32. int n,m,k;
  33. void init()
  34. {
  35. FILL(head,-);
  36. FILL(vis,);
  37. tot=;
  38. }
  39. void addedge(int u,int v)
  40. {
  41. e[tot]=edge(v,head[u]);
  42. head[u]=tot++;
  43. }
  44. void dfs(int u,int fa)
  45. {
  46. st[u]=++num;
  47. for(int i=head[u];~i;i=e[i].next)
  48. {
  49. int v=e[i].v;
  50. dep[v]=dep[u]+;
  51. dfs(v,u);
  52. }
  53. ed[u]=num;
  54. }
  55. void build(int l,int r,int rt)
  56. {
  57. for(int i=;i<k;i++)col[i][rt]=;
  58. if(l==r)return;
  59. int m=(l+r)>>;
  60. build(lson);
  61. build(rson);
  62. }
  63. void Pushdown(int rt)
  64. {
  65. for(int i=;i<k;i++)
  66. if(col[i][rt])
  67. {
  68. col[i][rt<<]+=col[i][rt];
  69. col[i][rt<<|]+=col[i][rt];
  70. col[i][rt]=;
  71. }
  72. }
  73. void update(int L,int R,int s,int c,int l,int r,int rt)
  74. {
  75. if(L<=l&&r<=R)
  76. {
  77. col[s][rt]+=c;
  78. return;
  79. }
  80. Pushdown(rt);
  81. int m=(l+r)>>;
  82. if(L<=m)update(L,R,s,c,lson);
  83. if(m<R)update(L,R,s,c,rson);
  84. }
  85. int query(int pos,int s,int l,int r,int rt)
  86. {
  87. if(l==r)
  88. {
  89. return col[s][rt];
  90. }
  91. Pushdown(rt);
  92. int m=(l+r)>>;
  93. if(pos<=m)return query(pos,s,lson);
  94. else return query(pos,s,rson);
  95. }
  96. int main()
  97. {
  98.  
  99. int t,a,b,op,cas=;
  100. scanf("%d",&t);
  101. while(t--)
  102. {
  103. scanf("%d%d%d",&n,&m,&k);
  104. init();
  105. for(int i=;i<n;i++)
  106. {
  107. scanf("%d%d",&a,&b);
  108. addedge(a,b);
  109. }
  110. num=;dep[]=;
  111. dfs(,-);
  112. build(,num,);
  113. printf("Case#%d:\n",cas++);
  114. while(m--)
  115. {
  116. scanf("%d",&op);
  117. if(op==)
  118. {
  119. scanf("%d",&a);
  120. printf("%d\n",query(st[a],(dep[a]+)%k,,num,));
  121. }
  122. else
  123. {
  124. scanf("%d%d",&a,&b);
  125. for(int i=;i<k;i++)
  126. {
  127. int s=((dep[a]+)%k+i)%k;
  128. update(st[a],ed[a],s,b*(i+),,num,);
  129. }
  130. }
  131. }
  132. }
  133. }

FZU2176(二维线段树+dfs)的更多相关文章

  1. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

  2. POJ2155 Matrix二维线段树经典题

    题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...

  3. HDU 1823 Luck and Love(二维线段树)

    之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...

  4. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  5. poj 1195:Mobile phones(二维线段树,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 De ...

  6. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

  7. HDU 4819 Mosaic (二维线段树)

    Mosaic Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total S ...

  8. HDU 4819 Mosaic --二维线段树(树套树)

    题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...

  9. HDU 4819 Mosaic(13年长春现场 二维线段树)

    HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...

随机推荐

  1. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  2. poj 2054 Color a Tree(贪婪)

    # include <stdio.h> # include <algorithm> # include <string.h> using namespace std ...

  3. xxx==null和xxx.equals(null)的区别

    如果xxx不是null的话,xxx==null将返回false,如果xxx是null的话,xxx将返回ture 而对xxx.equals(null)而言,他将永远返回false,因为如果xxx不是nu ...

  4. 基于visual Studio2013解决C语言竞赛题之1060寻找回文数

       题目 解决代码及点评 /* 60. 回文数指左右数字对称的数,如121,2112都是回文数.回文数猜想:取一任意十进制数,将其倒过来,并将这两个数相加, 然后把这个相加的和倒过来再与 ...

  5. Swift - 使用TableView的静态单元格进行页面布局

    通过使用静态单元格的列表,我们可以很方便的进行页面布局.下面通过一个“添加任务页面”来进行演示. 效果图如下: 实现步骤: 1,在storyboard中拖入一个TableViewController, ...

  6. 第13章、布局Layouts之RelativeLayout相对布局(从零開始学Android)

    RelativeLayout相对布局 RelativeLayout是一种相对布局,控件的位置是依照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最经常使用,也是最灵活的一种布 ...

  7. 我觉得主要靠积累,难度不是问题,主要靠时间积累,以及兴趣带来的学习能力(我觉得至少5年全职Qt开发经验,才能算精通)

    顺便想请教一下,你用QT有几年了? 3年不到 那感觉怎么样?是比较难,还是不难但需要时间才能掌握全部? 很多东西真的要拿来做项目了,才会懂.要靠积累.一开始看看理论貌似都很简单. 但是QT和C++本身 ...

  8. 【从零学习openCV】opecv操作像素

    1. 存取像素值 在opencv中能够直接对cv::Mat类型的图像调用at函数读取或赋值某个像素,我们用个简单的案例来说明: //在一张图像上增加椒盐噪声,image为输入图像.n为噪点个数 voi ...

  9. asp.net mvc 导出表格

    适合使用的场合: .net 中从前台中的table导出成excel文件,兼容各种浏览器. 使用工具: org.in2bits.MyXls.dll 从前台获取表格的thead和表格的tbody,将其转化 ...

  10. Swift - 导航条(UINavigationBar)的使用

    与导航控制器(UINavigationController)同时实现导航条和页面切换功能不同. 导航条(UINavgationBar)可以单独使用,添加至任何的UIView中.UINavigation ...