题目大意:给定一棵树。有三种操作:

  1. $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输。
  2. $1\;x:$结束第$x$个时刻的数据传输(保证合法)。
  3. $2\;x:$询问不经过点$x$的数据传输中重要度最大的是多少(无解输出$-1$)。

题解:可以发现一条路径对所有不在这条路径上的点有贡献,所以可以把这些区间给排除(树链剖分中的每一条链存下来),把其他位置加上一个数,可以给每个点维护一个大根堆。

考虑删除一个数,可以再开一个大根堆,表示删除的数,若两个堆顶元素相同,就弹出。

卡点:

C++ Code:

  1. #include <algorithm>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <iostream>
  5. #define maxn 100010
  6. inline int min(int a, int b) {return a < b ? a : b;}
  7. inline int max(int a, int b) {return a > b ? a : b;}
  8.  
  9. int head[maxn], cnt;
  10. struct Edge {
  11. int to, nxt;
  12. } e[maxn << 1];
  13. inline void add(int a, int b) {
  14. e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
  15. }
  16.  
  17. int n, m;
  18.  
  19. namespace SgT {
  20. struct node {
  21. std::priority_queue<int> A, D;
  22. inline void push(int x) {A.push(x);}
  23. inline void del(int x) {D.push(x);}
  24. inline int top() {
  25. while (!A.empty() && !D.empty() && A.top() == D.top()) A.pop(), D.pop();
  26. return A.empty() ? -1 : A.top();
  27. }
  28. } V[maxn << 2];
  29. int L, R, num, op;
  30.  
  31. void modify(int rt, int l, int r) {
  32. if (L <= l && R >= r) {
  33. if (op) V[rt].push(num);
  34. else V[rt].del(num);
  35. return ;
  36. }
  37. int mid = l + r >> 1;
  38. if (L <= mid) modify(rt << 1, l, mid);
  39. if (R > mid) modify(rt << 1 | 1, mid + 1, r);
  40. }
  41. void add(int __L, int __R, int __num) {
  42. L = __L, R = __R, num = __num, op = 1;
  43. modify(1, 1, n);
  44. }
  45. void del(int __L, int __R, int __num) {
  46. L = __L, R = __R, num = __num, op = 0;
  47. modify(1, 1, n);
  48. }
  49.  
  50. int __ask(int rt, int l, int r) {
  51. if (l == r) return V[rt].top();
  52. int mid = l + r >> 1, ans = V[rt].top();
  53. if (L <= mid) return max(ans, __ask(rt << 1, l, mid));
  54. else return max(ans, __ask(rt << 1 | 1, mid + 1, r));
  55. }
  56. int ask(int __L) {
  57. L = __L;
  58. return __ask(1, 1, n);
  59. }
  60. }
  61. using SgT::add;
  62. using SgT::del;
  63. using SgT::ask;
  64.  
  65. int fa[maxn], dep[maxn], sz[maxn];
  66. int dfn[maxn], idx, top[maxn], son[maxn];
  67. void dfs1(int u) {
  68. sz[u] = 1;
  69. for (int i = head[u]; i; i = e[i].nxt) {
  70. int v = e[i].to;
  71. if (v != fa[u]) {
  72. fa[v] = u;
  73. dep[v] = dep[u] + 1;
  74. dfs1(v);
  75. sz[u] += sz[v];
  76. if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
  77. }
  78. }
  79. }
  80. void dfs2(int u) {
  81. dfn[u] = ++idx;
  82. int v = son[u];
  83. if (v) top[v] = top[u], dfs2(v);
  84. for (int i = head[u]; i; i = e[i].nxt) {
  85. v = e[i].to;
  86. if (v != fa[u] && v != son[u]) {
  87. top[v] = v;
  88. dfs2(v);
  89. }
  90. }
  91. }
  92.  
  93. struct Modify {
  94. int u, v, x;
  95. } Mo[200010];
  96.  
  97. struct List {
  98. int l, r;
  99. inline friend bool operator < (const List &lhs, const List &rhs) {
  100. return lhs.l < rhs.l;
  101. }
  102. } S[maxn];
  103. void modify(int u, int v, int x, int op = 1) {
  104. int top = 0;
  105. while (::top[u] != ::top[v]) {
  106. if (dfn[::top[u]] < dfn[::top[v]]) std::swap(u, v);
  107. S[top++] = (List) {dfn[::top[u]], dfn[u]};
  108. u = fa[::top[u]];
  109. }
  110. if (dfn[u] > dfn[v]) std::swap(u, v);
  111. S[top++] = (List) {dfn[u], dfn[v]};
  112. std::sort(S, S + top);
  113. int reach = 1;
  114. for (int i = 0; i < top; reach = max(reach, S[i++].r + 1)) if (reach < S[i].l) {
  115. if (op) add(reach, S[i].l - 1, x);
  116. else del(reach, S[i].l - 1, x);
  117. }
  118. if (reach <= n) {
  119. if (op) add(reach, n, x);
  120. else del(reach, n, x);
  121. }
  122. }
  123. int main() {
  124. std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
  125. std::cin >> n >> m;
  126. for (int i = 1, a, b; i < n; i++) {
  127. std::cin >> a >> b;
  128. add(a, b);
  129. add(b, a);
  130. }
  131. dfs1(1);
  132. top[1] = 1;
  133. dfs2(1);
  134. for (int i = 1; i <= m; i++) {
  135. int op, x, y, z;
  136. std::cin >> op >> x;
  137. switch (op) {
  138. case 0:
  139. std::cin >> y >> z;
  140. Mo[i] = (Modify) {x, y, z};
  141. modify(x, y, z);
  142. break;
  143. case 1:
  144. modify(Mo[x].u, Mo[x].v, Mo[x].x, 0);
  145. break;
  146. case 2:
  147. std::cout << ask(dfn[x]) << '\n';
  148. break;
  149. }
  150. }
  151. return 0;
  152. }

  

[洛谷P3250][HNOI2016]网络的更多相关文章

  1. 洛谷P3250 [HNOI2016]网络(整体二分+树状数组+树剖)

    传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...

  2. 洛咕P3250 [HNOI2016]网络 整体二分

    这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...

  3. 洛谷 P1546 最短网络 Agri-Net

    题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...

  4. 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)

    洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...

  5. 洛谷P2812校园网络【Network of Schools加强版】

    题目背景 浙江省的几所\(OI\)强校的神犇发明了一种人工智能,可以\(AC\)任何题目,所以他们决定建立一个网络来共享这个软件.但是由于他们脑力劳动过多导致全身无力身体被\(♂\)掏\(♂\)空,他 ...

  6. luogu P3250 [HNOI2016]网络

    传送门 考虑只有一个询问,怎么使用暴力枚举最快的得到答案.因为要求最大的,所以可以把链按权值从大往小排序,然后往后扫,找到一个没有交的就是答案,直接退出 一堆询问,可以考虑整体二分,先二分一个值\(m ...

  7. 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]

    洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...

  8. 【题解】洛谷P1262 间谍网络 (强连通分量缩点)

    洛谷P1262:https://www.luogu.org/problemnew/show/P1262 思路 一看题目就知道是强连通分量缩点 当图中有强连通分量时 将其缩点 我们可以用dfn数组判断是 ...

  9. 洛谷 1262 间谍网络 Tarjan 图论

    洛谷 1262 图论 tarjan 并不感觉把这道题目放在图的遍历中很合适,虽然思路比较简单但是代码还是有点多的,, 将可收买的间谍的cost值设为它的价格,不可购买的设为inf,按照控制关系连图,T ...

随机推荐

  1. c++ 重载运算与类型转换

    1. 基础概念 重载的运算符是具有特殊名字的函数:(重载运算符函数,运算符函数.重载运算符) 依次包含返回类型,函数名(operator=),参数列表,函数体. 只有重载的函数调用运算符operato ...

  2. Hive实现自增列

    1.用row_number()函数生成代理键 ) max_id from id_test) t2; 2.用UDFRowSequence生成代理键              ——报错? add jar ...

  3. JMeter常用元器件

    测试计划, 是整个工程的根节点, 可以取别名, 并添加注释, 里面的设置是全局变量: 线程组, 是一组线程的集合, 可以取别名, 并添加注释, 里面的设置只对本线程组有效: HTTP请求, 也就是取样 ...

  4. ortp打印日志

    //向字符串中打印数据 static char* ms_strdup_vprintf(const char *fmt, va_list ap) { ; char *p,*np; #ifndef WIN ...

  5. CSS3自定义字体

    原文摘自:https://www.cnblogs.com/moqiutao/archive/2015/12/23/5070463.html 总节: 1) 定义字体标准格式: @font-face { ...

  6. GIT: 分布式开发 代码管理工具使用命令大全

    代码管理工具: GIT     什么是GIT? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常 ...

  7. 41. Maximum Subarray

    Description Given an array of integers, find a contiguous subarray which has the largest sum. The su ...

  8. 《Git学习指南》学习笔记(二)

    第三章 提交究竟是什么 每次提交都会生成一个40位的散列值.只要知道散列值,我们就可以恢复到该次提交,这个操作也被称之为检出(checkout)操作. 访问权限与时间戳 Git会保存每个文件原有的访问 ...

  9. (转)GEM -次表面散射的实时近似

    次表面散射(Subsurface Scattering),简称SSS,或3S,是光射入非金属材质后在内部发生散射, 最后射出物体并进入视野中产生的现象, 即光从表面进入物体经过内部散射,然后又通过物体 ...

  10. OpenMPI运行问题:enough slots available in the system

    版本: Open MPI 3.0.1 编译好可执行的C语言程序后,使用 mpirun -np 3 Test 命令,发现没有正常运行,而是报错: There are not enough slots a ...