题目链接  ...Wait for it...

考虑树链剖分。

对于树上的每个点开一个set,记录当前该节点上所有的girls。

每个节点初始的权值为set中的最小值。

询问的时候每次在路径上寻找最小值,并返回这个点的编号。

然后把这个点的set的第一个元素取出,换成下一个元素。

因为女孩总数不超过1e5,所以总查询次数不会超过1e5

修改操作用lazy标记就可以了。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define rep(i, a, b) for (int i(a); i <= (b); ++i)
  6. #define dec(i, a, b) for (int i(a); i >= (b); --i)
  7. #define lson i << 1, L, mid
  8. #define rson i << 1 | 1, mid + 1, R
  9. #define ls i << 1
  10. #define rs i << 1 | 1
  11. #define MP make_pair
  12. #define fi first
  13. #define se second
  14.  
  15. typedef long long LL;
  16. typedef pair <LL, int> PII;
  17.  
  18. const int N = 1e5 + 10;
  19. const LL inf = 1e18;
  20.  
  21. int n, m, q;
  22. int id, cnt = 0;
  23. int ret[N];
  24. int at[N], sz[N], son[N], top[N], f[N], in[N], out[N], deep[N], father[N];
  25. vector <int> v[N];
  26. set <PII> s[N];
  27. LL lazy[N << 2];
  28. PII t[N << 2];
  29.  
  30. void dfs(int x, int fa, int dep){
  31. sz[x] = 1;
  32. son[x] = 0;
  33. father[x] = fa;
  34. deep[x] = dep;
  35. for (auto u : v[x]){
  36. if (u == fa) continue;
  37. dfs(u, x, dep + 1);
  38. sz[x] += sz[u];
  39. if (sz[son[x]] < sz[u]) son[x] = u;
  40. }
  41. }
  42.  
  43. void dfs2(int x, int tp){
  44. top[x] = tp;
  45. in[x] = f[x] = ++id;
  46. if (son[x]) dfs2(son[x], tp);
  47. for (auto u : v[x]){
  48. if (u == father[x] || u == son[x]) continue;
  49. dfs2(u, u);
  50. }
  51. out[x] = id;
  52. }
  53.  
  54. void pushup(int i){
  55. t[i] = min(t[ls], t[rs]);
  56. }
  57.  
  58. void pushdown(int i){
  59. if (lazy[i]){
  60. lazy[ls] += lazy[i];
  61. lazy[rs] += lazy[i];
  62. t[ls].fi += lazy[i];
  63. t[rs].fi += lazy[i];
  64. lazy[i] = 0;
  65. }
  66. }
  67.  
  68. void build(int i, int L, int R){
  69. lazy[i] = 0;
  70. if (L == R){
  71. t[i] = *s[L].begin();
  72. return;
  73. }
  74.  
  75. int mid = (L + R) >> 1;
  76. build(lson);
  77. build(rson);
  78. pushup(i);
  79. }
  80.  
  81. void update(int i, int L , int R , int l, int r, LL val){
  82. if (l <= L && R <= r){
  83. lazy[i] += val;
  84. t[i].fi += val;
  85. return;
  86. }
  87.  
  88. pushdown(i);
  89. int mid = (L + R) >> 1 ;
  90. if (l <= mid) update(lson, l, r, val);
  91. if (r > mid) update(rson, l, r, val);
  92. pushup(i);
  93. }
  94.  
  95. void modify(int i, int L, int R, int x){
  96. if (L == R){
  97. s[L].erase(s[L].begin());
  98. t[i] = *s[L].begin();
  99. t[i].fi += lazy[i];
  100. return;
  101. }
  102. pushdown(i);
  103. int mid = (L + R) >> 1 ;
  104. if (x <= mid) modify(lson, x) ;
  105. else modify(rson, x);
  106. pushup(i);
  107. }
  108.  
  109. PII query(int i, int L, int R, int l, int r){
  110. if (l <= L && R <= r) return t[i];
  111. pushdown(i);
  112. int mid = (L + R) >> 1 ;
  113. if (r <= mid) return query(lson, l, r);
  114. if (l > mid) return query(rson, l, r);
  115. return min(query(lson, l, r), query(rson, l, r));
  116. }
  117.  
  118. int Query(int x, int y){
  119. PII ans = PII(inf, 0);
  120. while (top[x] ^ top[y]){
  121. if (deep[top[x]] < deep[top[y]]) swap(x, y);
  122. ans = min(ans, query(1, 1, n, f[top[x]], f[x]));
  123. x = father[top[x]];
  124. }
  125. if (deep[x] > deep[y]) swap(x, y);
  126. ans = min(ans, query(1, 1, n, f[x], f[y]));
  127. return ans.se;
  128. }
  129.  
  130. int main(){
  131.  
  132. scanf("%d%d%d", &n, &m, &q);
  133. rep(i, 2, n){
  134. int x, y;
  135. scanf("%d%d", &x, &y);
  136. v[x].push_back(y);
  137. v[y].push_back(x);
  138. }
  139.  
  140. dfs(1, 0, 0);
  141. dfs2(1, 1);
  142.  
  143. rep(i, 1, n) s[i].insert(MP(inf, 0));
  144. at[0] = N - 1;
  145.  
  146. rep(i, 1, m){
  147. int x;
  148. scanf("%d", &x);
  149. at[i] = x;
  150. s[f[x]].insert(MP(i, i));
  151. }
  152.  
  153. build(1, 1, n);
  154.  
  155. while (q--){
  156. int op, x, y, lim;
  157. LL val;
  158. scanf("%d", &op);
  159. if (op == 2){
  160. scanf("%d%lld", &x, &val);
  161. update(1, 1, n, in[x], out[x], val);
  162. }
  163. else{
  164. scanf("%d%d%d", &x, &y, &lim);
  165. cnt = 0;
  166. while (lim--){
  167. int idx = Query(x, y);
  168. if (idx == 0) break;
  169. ret[++cnt] = idx;
  170. modify(1, 1, n, f[at[idx]]);
  171. }
  172. printf("%d", cnt);
  173. rep(i, 1, cnt) printf(" %d", ret[i]);
  174. putchar(10);
  175. }
  176. }
  177.  
  178. return 0;
  179. }

Codeforces 696E ...Wait for it...(树链剖分)的更多相关文章

  1. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  2. Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)

    题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...

  3. Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分

    D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...

  4. 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)

    题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...

  5. Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  6. Codeforces 704E Iron Man [树链剖分,计算几何]

    Codeforces 这题--真是搞死我了-- 好不容易下定了决心要不颓废,要写题,结果一调就调了十几个小时-- 思路 我们发现在树上做非常不舒服,于是树链剖分之后一次在重链上的移动就可以看做是在df ...

  7. D. Happy Tree Party CodeForces 593D【树链剖分,树边权转点权】

    Codeforces Round #329 (Div. 2) D. Happy Tree Party time limit per test 3 seconds memory limit per te ...

  8. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  9. CodeForces - 343D 树链剖分

    题目链接:http://codeforces.com/problemset/problem/343/D 题意:给定一棵n个n-1条边的树,起初所有节点权值为0,然后m个操作. 1 x:把x为根的子树的 ...

随机推荐

  1. 1、python-初探

    语言包括编译型语言和解释型语言编译型:全部翻译,再执行:c.c++解释型:边执行边翻译:python.php.java.c#.perl.ruby.javascript 一.系统位数32位系统内存的最大 ...

  2. ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study

    262144K   Ryuji is not a good student, and he doesn't want to study. But there are n books he should ...

  3. bash数组操作-定义/初始化/赋值…

    数组:     连续的多个独立内存空间,每个内存空间相当于一个变量     数组元素:数组名+索引         索引:从0开始编号             声明数组:         declar ...

  4. Python虚拟机之if控制流(一)

    Python虚拟机中的if控制流 在所有的编程语言中,if控制流是最简单也是最常用的控制流语句.下面,我们来分析一下在Python虚拟机中对if控制流的实现 # cat demo.py a = 1 i ...

  5. Makefile基础(二)

    上一章:C语言之Makefile基础(一) 上一章的Makefile写的中规中矩,比较繁琐,是为了讲清楚基本概念,其实Makefile有很多灵活的写法,可以写的更简洁,同时减少出错的可能 一个目标依赖 ...

  6. github仓库主页介绍

  7. 《Scrum实战》第2次课【取得大家的支持】课后作业汇总

    作业:<变革之心>读后感 孟帅: 2017-7-12http://www.cnblogs.com/mengshuai1982/p/7153985.html

  8. Vmware复制完好的linux目录后网卡操作

    目录 Vmware复制完好的linux目录后网卡操作 修改/etc/udev/rules.d/70-persistent-net.rules 修改网卡配置文件 重启查看 Vmware复制完好的linu ...

  9. [automator篇][5]Viewer 提示connect to adb fail

    7. UIAutomatorViewer提示: Unable to connect to adb. Check if adb is installed correctly 解决,sdk升级到了25产生 ...

  10. TOJ 3581: 最简IPv6表示

    3581: 最简IPv6表示  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 121   ...