【LG3250】[HNOI2016]网络

题面

洛谷

题解

30pts

对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\log n)\)。

另20pts

对于无删除操作的,用线段树维护,

我们将一条路径的补集全部打上那条路径重要度的标记,这样我们断一条边时直接单点查询即可。

据说这样子再改改可以变成一种树剖加堆的做法,但是好像现在在bzoj被卡了

100pts

想到二分答案,若所有权值\(\geq mid\)的路径都过\(x\),那么\(ans<mid\),反之若有不过\(x\)的,则说明\(ans\geq mid\)。

这个可以用树套树维护,因为树状数组套线段树会炸空间,所以就线段树套平衡树,复杂度\(O(m\log ^3n)\)。

考虑整体二分,那么我们按照套路按时间加入,将一条路径树上差分,

碰到一次查询直接看经过它的路径条数即可,复杂度\(O(m\log^2 n)\)。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 1e5 + 5, MAX_M = 2e5 + 5;
struct Graph { int to, next; } e[MAX_N << 1]; int fir[MAX_N], e_cnt;
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; }
void Add_Edge(int u, int v) { e[e_cnt] = (Graph){v, fir[u]}; fir[u] = e_cnt++; }
int dep[MAX_N], fa[MAX_N], size[MAX_N], top[MAX_N], son[MAX_N];
int L[MAX_N], R[MAX_N], tim;
void dfs1(int x) {
dep[x] = dep[fa[x]] + 1, size[x] = 1;
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to; if (v == fa[x]) continue;
fa[v] = x, dfs1(v), size[x] += size[v];
if (size[son[x]] < size[v]) son[x] = v;
}
}
void dfs2(int x, int tp) {
top[x] = tp, L[x] = ++tim;
if (son[x]) dfs2(son[x], tp);
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to; if (v == son[x] || v == fa[x]) continue;
dfs2(v, v);
}
R[x] = tim;
}
int LCA(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
int N, M;
struct Option { int op, a, b, lca, v, id; } q[MAX_M], lq[MAX_M], rq[MAX_M];
int ans[MAX_M];
int c[MAX_N];
inline int lb(int x) { return x & -x; }
int sum(int x) { int res = 0; while (x) res += c[x], x -= lb(x); return res; }
void add(int x, int v) { while (x <= N) c[x] += v, x += lb(x); }
void Div(int lval, int rval, int st, int ed) {
if (st > ed) return ;
if (lval == rval) {
for (int i = st; i <= ed; i++)
if (q[i].op == 2) ans[q[i].id] = lval;
return ;
}
int mid = (lval + rval) >> 1, lt = 0, rt = 0, cnt = 0;
for (int i = st; i <= ed; i++) {
if (q[i].op != 2) {
if (q[i].v > mid) {
int v = q[i].op ? -1 : 1;
cnt += v;
add(L[q[i].a], v), add(L[q[i].b], v), add(L[q[i].lca], -v);
if (fa[q[i].lca]) add(L[fa[q[i].lca]], -v);
rq[++rt] = q[i];
} else lq[++lt] = q[i];
} else {
int res = sum(R[q[i].a]) - sum(L[q[i].a] - 1);
if (cnt <= res) lq[++lt] = q[i];
else rq[++rt] = q[i];
}
}
for (int i = 1; i <= rt; i++) {
if (rq[i].op != 2) {
if (rq[i].v > mid) {
int v = rq[i].op ? 1 : -1;
add(L[rq[i].a], v), add(L[rq[i].b], v), add(L[rq[i].lca], -v);
if (fa[rq[i].lca]) add(L[fa[rq[i].lca]], -v);
}
}
}
for (int i = 1; i <= lt; i++) q[st + i - 1] = lq[i];
for (int i = 1; i <= rt; i++) q[st + lt - 1 + i] = rq[i];
Div(lval, mid, st, st + lt - 1);
Div(mid + 1, rval, st + lt, ed);
}
int h[MAX_N], cnt;
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
clearGraph();
N = gi(), M = gi();
for (int i = 1; i < N; i++) {
int u = gi(), v = gi();
Add_Edge(u, v), Add_Edge(v, u);
}
dfs1(1), dfs2(1, 1);
int q_cnt = 0;
for (int i = 1; i <= M; i++) {
int op = gi();
if (op == 0) {
int a = gi(), b = gi();
q[i] = (Option){op, a, b, LCA(a, b), gi(), 0};
h[++cnt] = q[i].v;
}
if (op == 1) q[i] = q[gi()], q[i].op = 1;
if (op == 2) q[i] = (Option){op, gi(), 0, 0, 0, ++q_cnt};
}
h[++cnt] = -1;
sort(&h[1], &h[cnt + 1]); cnt = unique(&h[1], &h[cnt + 1]) - h - 1;
for (int i = 1; i <= M; i++) if (q[i].op != 2) q[i].v = lower_bound(&h[1], &h[cnt + 1], q[i].v) - h;
Div(1, cnt, 1, M);
for (int i = 1; i <= q_cnt; i++) printf("%d\n", h[ans[i]]);
return 0;
}

【LG3250】[HNOI2016]网络的更多相关文章

  1. BZOJ 4538: [Hnoi2016]网络 [整体二分]

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  2. 4538: [Hnoi2016]网络

    4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...

  3. [HNOI2016]网络 树链剖分,堆

    [HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...

  4. 【BZOJ4538】[Hnoi2016]网络 整体二分+树状数组

    [BZOJ4538][Hnoi2016]网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互 ...

  5. Luogu-3250 [HNOI2016]网络

    Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...

  6. (BZOJ4538)HNOI2016 网络

    HNOI2016 Day1 T2 网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互时,数 ...

  7. P3250 [HNOI2016]网络

    LINK:网络 一棵树 每次添加一条路径 或者删除之前的一条路径 或询问除了不经过某个点之外剩下的最大值. 一个显然的思路 对于一条路径的权值我们直接把权值塞上去 标记永久化一下即可. 考虑如何求答案 ...

  8. BZOJ4538 : [Hnoi2016]网络

    求出这棵树的dfs序,对于一条链$u-v$,假设$st[u]\leq st[v]$,那么一条链不经过点$x$当且仅当它满足下面任意一个条件: 1.$st[v]<st[x]$ 2.$st[u]&g ...

  9. HNOI2016 网络

    题目 朴素算法 在线. 树链剖分套一个堆. 时间复杂度\(O(n (\log n)^3)\). 分治 朴素算法中,套一个堆是为了支持删除操作. 采用以下分治可以避免删除操作: 每次对时间\([l,r] ...

随机推荐

  1. NSOperation的使用细节 [2]

    NSOperation的使用细节 [2] 这一节我们来写自定义nonconcurrent的operation,自定义nonconcurrent的operation很简单,重写main方法,之后处理好c ...

  2. 使用UISearchDisplayController

    使用UISearchDisplayController 虽然UISearchDisplayController名字中带有controller,可他不是一个UIView相关的controller,因为, ...

  3. 在 vSphere 5.x/6.0 中配置 Network Dump Collector 服务 (2002954)

    vmware KB: https://kb.vmware.com/s/article/2002954?lang=zh_CN 重点配置命令: 使用 vSphere Client 连接到 vCenter ...

  4. 五十个小技巧提高PHP执行效率

    在项目开发过程中,经常遇到了一些PHP处理程序性能底下的情况,程序运行在centos+nginx环境,虽然这个有很多的原因如:服务器本身配置,运行环境nginx服务,php-fpm配置等等,更多有一点 ...

  5. shell study

    目录 shell记录 执行脚本 变量使用 注释 shell传递参数 运算符 echo printf test 流程控制 if ... else ... for while until case 跳出循 ...

  6. ubuntu 14.04 安装 openvswitch

    安装 openvswitch (这里以openvswitch lib 分支为例) 如果没有安装git,如果有请跳过 $ sudo apt-get install git install ovs $ g ...

  7. linux下统计目录下所有子目录的大小

    du -sh * --exclude=tar |awk '{v=substr($1,length($1),1)}v=="G"{$0="1G "$0}v==&qu ...

  8. [Java多线程] LinkedBlockingQueue

    java.util.concurrent包下的新类.LinkedBlockingQueue就是其中之一,是一个阻塞的线程安全的队列,底层采用链表实现. LinkedBlockingQueue Link ...

  9. 9、Android---UI---Material Design

    9.1.什么是Material Design 由谷歌的设计师基于传统优秀设计原则,结合丰富的创意和科学技术所发明的一套全新的界面设计语言 包含了视觉.运行.互动等效果 Material Design的 ...

  10. js检测是够断网

    方法 一 navigator.onLine   这个html5的 navigator的新特性可以很简单帮我们搞定 HTML5为此定义了一个navigator.onLine属性,这个属性值为true表示 ...