4538: [Hnoi2016]网络
4538: [Hnoi2016]网络
分析:
整体二分。
对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点。如果是 ,那么这次询问的答案在[l,mid-1]之间,否则在[mid,r]之间。
判断是否所有的路径经过一个点:等价于数经过这个点的路径条数,对于一条路径(u->v),可以在u,v处+1,在lca处-1,在fa[lca]处-1,然后询问一个点的子树和即可。
多次询问,整体二分即可。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
struct Data { int ty, a, b, v, c; } A[N], B[N], C[N];
struct Edge { int to, nxt; } e[N << ];
int head[N], f[N][], dfn[N], dep[N], siz[N], ans[N], En, Index; inline void add_edge(int u,int v) {
++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
++En; e[En].to = u, e[En].nxt = head[v]; head[v] = En;
}
int LCA(int u,int v) {
if (dep[u] < dep[v]) swap(u, v);
int d = dep[u] - dep[v];
for (int i = ; ~i; --i) if ((d >> i) & ) u = f[u][i];
if (u == v) return u;
for (int i = ; ~i; --i) if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
return f[u][];
}
void dfs(int u) {
for (int j = ; j <= ; ++j) f[u][j] = f[f[u][j - ]][j - ];
dep[u] = dep[f[u][]] + ;
dfn[u] = ++Index; siz[u] = ;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v == f[u][]) continue;
f[v][] = u;
dfs(v);
siz[u] += siz[v];
}
}
struct Bit{
int sum[N << ], n;
void clear() { memset(sum, , sizeof(sum)); }
void update(int p,int v) { if (p == ) return ; for (; p <= n; p += (p & (-p))) sum[p] += v; }
int query(int p) {
int ans = ;
for (; p; p -= (p & (-p))) ans += sum[p];
return ans;
}
int Ask(int l,int r) { return query(r) - query(l - ); }
}bit;
void add(Data &A,int ty) {
ty = ty ? - : ;
bit.update(dfn[A.a], ty);
bit.update(dfn[A.b], ty);
bit.update(dfn[A.c], -ty);
bit.update(dfn[f[A.c][]], -ty);
}
void solve(int l,int r,int H,int T) {
if (H > T) return ;
if (l == r) {
for (int i = H; i <= T; ++i) if (A[i].ty == ) ans[A[i].b] = l;
return ;
}
int mid = (l + r + ) >> , cl = H, cr = T, now = ;
for (int i = H; i <= T; ++i) {
if (A[i].ty <= ) {
if (A[i].v < mid) B[cl ++] = A[i];
else add(A[i], A[i].ty), B[cr --] = A[i], now += (A[i].ty ? - : );
}
else {
int t = bit.Ask(dfn[A[i].a], dfn[A[i].a] + siz[A[i].a] - );
if (t == now) B[cl ++] = A[i];
else B[cr --] = A[i];
}
}
for (int i = H; i <= T; ++i) if (A[i].ty <= && A[i].v >= mid) add(A[i], !A[i].ty);
for (int i = H; i < cl; ++i) A[i] = B[i];
for (int i = cl; i <= T; ++i) A[i] = B[T - i + cl];
solve(l, mid - , H, cl - );
solve(mid, r, cl, T);
}
int main() {
int n = read(), m = read(), mx = , id = , tot = , now = ; bit.n = n;
for (int i = ; i < n; ++i) {
int u = read(), v = read();
add_edge(u, v);
}
dfs();
for (int i = ; i <= m; ++i) {
int opt = read();
if (opt == ) {
int u = read(), v = read(), w = read(), z = LCA(u, v);
A[i] = (Data){opt, u, v, w, z};
mx = max(mx, w);
} else if (opt == ) {
int t = read();
A[i] = A[t]; A[i].ty = ;
} else if (opt == ) {
int x = read(); ++id;
A[i] = (Data){, x, id, , };
}
}
for (int i = ; i <= m; ++i) {
if (A[i].ty <= ) add(A[i], A[i].ty), now += (A[i].ty ? - : ), B[++tot] = A[i];
else {
if (bit.Ask(dfn[A[i].a], dfn[A[i].a] + siz[A[i].a] - ) == now) ans[A[i].b] = -;
else B[++tot] = A[i];
}
}
for (int i = ; i <= tot; ++i) A[i] = B[i];
bit.clear();
solve(-, mx, , tot);
for (int i = ; i <= id; ++i) printf("%d\n", ans[i]);
return ;
}
4538: [Hnoi2016]网络的更多相关文章
- BZOJ 4538: [Hnoi2016]网络 [整体二分]
4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...
- 【bzoj】4538: [Hnoi2016]网络
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4538 维护一个数据结构支持对于一颗树的操作,需要支持: 1.对于树上的一条路径上的每个点上 ...
- bzoj 4538: [Hnoi2016]网络
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有服 ...
- 【LG3250】[HNOI2016]网络
[LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...
- [HNOI2016]网络 树链剖分,堆
[HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...
- 【BZOJ4538】[Hnoi2016]网络 整体二分+树状数组
[BZOJ4538][Hnoi2016]网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互 ...
- Luogu-3250 [HNOI2016]网络
Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...
- (BZOJ4538)HNOI2016 网络
HNOI2016 Day1 T2 网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互时,数 ...
- P3250 [HNOI2016]网络
LINK:网络 一棵树 每次添加一条路径 或者删除之前的一条路径 或询问除了不经过某个点之外剩下的最大值. 一个显然的思路 对于一条路径的权值我们直接把权值塞上去 标记永久化一下即可. 考虑如何求答案 ...
随机推荐
- 使用django的admin的后台管理界面
django的admin后台管理界面是方便我们对数据库操作的 是一个在浏览器显示的 图形化界面数据库操作 我们先在django中的admin中把我们需要在图形化界面中进行操作的表导入进去: 先把m ...
- iOS设计模式 - 中介者
iOS设计模式 - 中介者 原理图 说明 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 注:中介者对象本身没有复用价值 ...
- [UI] 精美UI界面欣赏[10]
精美UI界面欣赏[10]
- 铁乐学Python_day12_装饰器
[函数的有用信息] 例: def login(user, pwd): ''' 功能:登录调用 参数:分别有user和pwd,作用分别是用户和密码: return: 返回值是登录成功与否(True,Fa ...
- 铁乐学python_day04-作业
1,写代码,有如下列表,按照要求实现每一个功能 li = ['alex', 'wusir', 'eric', 'rain', 'alex'] 计算列表的长度并输出 print(len(li)) 答:结 ...
- DoraHacks的笔记
DoraHacks的笔记
- Docker镜像搭建Linux下samba共享目录
Samba 是 SMB/CIFS 网络协议的重新实现, 它作为 NFS 的补充使得在 Linux.OS/2.DOS 和 Windows 系统中进行文件共享.打印机共享更容易实现.SMB协议是客户机/服 ...
- 【洛谷】【扩欧】P1516 青蛙的约会
[题目描述] 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有 ...
- 怎样批量提取JPG照片的文件名
用批处理做吧, @echo off dir /a-d /b >./list.txt 把上面两句代码用记事本保存为“list.bat”(不要引号) 然后把这个文件放到你要提取文件名的文件夹里,就是 ...
- 如何1秒批量提取电脑文件夹中的所有文件、文件夹名字到txt/excel
01 在工作,我们经常会遇到这样的情况,有时候我们在一个文件夹中放了很多的文件,或者是这个文件夹中有很多的子文件夹,每一个子文件夹的名字又不同,也没有什么样的规律, 02 但是我们要整理一下这个文 ...