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

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

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

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

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <iostream>
#define maxn 100010
inline int min(int a, int b) {return a < b ? a : b;}
inline int max(int a, int b) {return a > b ? a : b;} int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
} int n, m; namespace SgT {
struct node {
std::priority_queue<int> A, D;
inline void push(int x) {A.push(x);}
inline void del(int x) {D.push(x);}
inline int top() {
while (!A.empty() && !D.empty() && A.top() == D.top()) A.pop(), D.pop();
return A.empty() ? -1 : A.top();
}
} V[maxn << 2];
int L, R, num, op; void modify(int rt, int l, int r) {
if (L <= l && R >= r) {
if (op) V[rt].push(num);
else V[rt].del(num);
return ;
}
int mid = l + r >> 1;
if (L <= mid) modify(rt << 1, l, mid);
if (R > mid) modify(rt << 1 | 1, mid + 1, r);
}
void add(int __L, int __R, int __num) {
L = __L, R = __R, num = __num, op = 1;
modify(1, 1, n);
}
void del(int __L, int __R, int __num) {
L = __L, R = __R, num = __num, op = 0;
modify(1, 1, n);
} int __ask(int rt, int l, int r) {
if (l == r) return V[rt].top();
int mid = l + r >> 1, ans = V[rt].top();
if (L <= mid) return max(ans, __ask(rt << 1, l, mid));
else return max(ans, __ask(rt << 1 | 1, mid + 1, r));
}
int ask(int __L) {
L = __L;
return __ask(1, 1, n);
}
}
using SgT::add;
using SgT::del;
using SgT::ask; int fa[maxn], dep[maxn], sz[maxn];
int dfn[maxn], idx, top[maxn], son[maxn];
void dfs1(int u) {
sz[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa[u]) {
fa[v] = u;
dep[v] = dep[u] + 1;
dfs1(v);
sz[u] += sz[v];
if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
}
}
}
void dfs2(int u) {
dfn[u] = ++idx;
int v = son[u];
if (v) top[v] = top[u], dfs2(v);
for (int i = head[u]; i; i = e[i].nxt) {
v = e[i].to;
if (v != fa[u] && v != son[u]) {
top[v] = v;
dfs2(v);
}
}
} struct Modify {
int u, v, x;
} Mo[200010]; struct List {
int l, r;
inline friend bool operator < (const List &lhs, const List &rhs) {
return lhs.l < rhs.l;
}
} S[maxn];
void modify(int u, int v, int x, int op = 1) {
int top = 0;
while (::top[u] != ::top[v]) {
if (dfn[::top[u]] < dfn[::top[v]]) std::swap(u, v);
S[top++] = (List) {dfn[::top[u]], dfn[u]};
u = fa[::top[u]];
}
if (dfn[u] > dfn[v]) std::swap(u, v);
S[top++] = (List) {dfn[u], dfn[v]};
std::sort(S, S + top);
int reach = 1;
for (int i = 0; i < top; reach = max(reach, S[i++].r + 1)) if (reach < S[i].l) {
if (op) add(reach, S[i].l - 1, x);
else del(reach, S[i].l - 1, x);
}
if (reach <= n) {
if (op) add(reach, n, x);
else del(reach, n, x);
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m;
for (int i = 1, a, b; i < n; i++) {
std::cin >> a >> b;
add(a, b);
add(b, a);
}
dfs1(1);
top[1] = 1;
dfs2(1);
for (int i = 1; i <= m; i++) {
int op, x, y, z;
std::cin >> op >> x;
switch (op) {
case 0:
std::cin >> y >> z;
Mo[i] = (Modify) {x, y, z};
modify(x, y, z);
break;
case 1:
modify(Mo[x].u, Mo[x].v, Mo[x].x, 0);
break;
case 2:
std::cout << ask(dfn[x]) << '\n';
break;
}
}
return 0;
}

  

[洛谷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. explain获得使用的key的数据

    bool Explain_join::explain_key_and_len() { if (tab->ref.key_parts) return explain_key_and_len_ind ...

  2. QT 标题栏隐藏可拖拽

    这个也是我网上找到了 为了方便,记录一下 void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void ...

  3. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第3章.Tomcat

    第3章--Tomcat Tomcat安装与运行 Tomcat:目前最常用的基于java的web应用服务器 本课程中所有的Java代码最终都需要部署到Tomcat中运行 Tomcat的配置文件是XML的 ...

  4. java后台接受web前台传递的数组参数

    前台发送:&warning_type[]=1,2 &warning_type=1,2 后台接收:(@RequestParam(value = "param[]") ...

  5. 【xmlHttp_Class 远程访问类】使用说明

    类名:xmlHttp_Class 说明:远程获取外部网站数据信息或执行一个外部网站程序 目录: 类型 名称 参数 返回 说明 属性 [必需] [xmlHttp].url = [urlString] - ...

  6. Java反射篇学习笔记

    今天重新学习了java中的反射,写一篇学习笔记总结一下.代码基本都是照着两篇博客敲的: 参考一:   https://blog.csdn.net/sinat_38259539/article/deta ...

  7. Python3中@的作用

    可能是自己理解能力差,网上看了一大堆教程,完全没搞懂. 自己敲几行代码,终于理解是怎么回事了. #python 3.6 #!/usr/bin/env python # -*- coding:utf-8 ...

  8. vim常用命令—撤销与反撤销

    命令模式下(即按ESC后的模式) u 撤销 Ctrl r (组合键) 反撤销<后悔撤销>

  9. 深度学习图像分割——U-net网络

    写在前面: 一直没有整理的习惯,导致很多东西会有所遗忘,遗漏.借着这个机会,养成一个习惯. 对现有东西做一个整理.记录,对新事物去探索.分享. 因此博客主要内容为我做过的,所学的整理记录以及新的算法. ...

  10. JQuery中each方法实现

    each()函数是基本上所有的框架都提供了的一个工具类函数,通过它,你可以遍历对象.数组的属性值并进行处理. jQuery和jQuery对象都实现了该方法,对于jQuery对象,只是把each方法简单 ...