[CTSC2008]网络管理 [整体二分]
题面
所有事件按时间排序
按值划分下放
把每一个修改
改成一个删除一个插入
对于一个查询
直接查这个段区间有多少合法点
如果查询值大于等于目标值 进入左区间
如果一个查询无解
那么它要求第k大无解
k > 路径长 用lca维护即可
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#define Sqr(x) ((x)*(x))
using namespace std;
const int N = 8e4 + 5;
const int inf = 1e8 + 5;
struct Edge{
int v, next;
}edge[N << 1];
int head[N], esize;
inline void addedge(int x, int y){
edge[++esize] = (Edge){y, head[x]};
head[x] = esize;
}
struct Node{
int t, x, y, w, d;
bool type; //0是插入 1是查询
}node[N << 2], p1[N << 2], p2[N << 2];
int n, m, nsize, a[N], ans[N];
int tim, dfn[N], top[N], son[N], fa[N], size[N], rf[N], dep[N];
bool flag[N];
struct BIT{
int w[N];
void ins(int x, int d){while(x <= n){w[x] += d; x += x & -x;}}
int qry(int x){int res = 0; while(x){res += w[x]; x -= x & -x;} return res;}
}bit;
inline void addnode(int x1, int x2, int x3, int x4, int x5, bool x6){
++nsize, node[nsize].t = x1, node[nsize].x = x2, node[nsize].y = x3,
node[nsize].w = x4, node[nsize].d = x5, node[nsize].type = x6;
}
void dfs1(int x, int ff){
dep[x] = dep[ff] + 1, size[x] = 1, fa[x] = ff;
for(int i = head[x], vv; ~i; i = edge[i].next){
vv = edge[i].v; if(vv == ff) continue;
dfs1(vv, x);
size[x] += size[vv];
if(size[son[x]] < size[vv]) son[x] = vv;
}
}
void dfs2(int x, int tp){
top[x] = tp, dfn[x] = ++tim, rf[tim] = x;
if(son[x]) dfs2(son[x], tp); else return;
for(int i = head[x], vv; ~i; i = edge[i].next){
vv = edge[i].v; if(vv == fa[x] || vv == son[x]) continue;
dfs2(vv, vv);
}
}
int LCA(int x, int y){
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
int qry(int x, int y){
int res = 0;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res += bit.qry(dfn[x]) - bit.qry(dfn[top[x]] - 1);
x = fa[top[x]];
}
if(dep[x] < dep[y]) swap(x, y); res += bit.qry(dfn[x]) - bit.qry(dfn[y] - 1);
return res;
}
void erfn(int L, int R, int l, int r){
if(L > R) return;
if(l == r){
for(int i = L; i <= R; ++i)
if(node[i].type && ~ans[node[i].t]) ans[node[i].t] = l;
return ;
}
int mid = l + ((r - l) >> 1);
int t1 = 0, t2 = 0;
for(int i = L; i <= R; ++i){
if(node[i].type) {
int cnt = qry(node[i].x, node[i].y);
if(cnt >= node[i].w) p2[++t2] = node[i];
else node[i].w -= cnt, p1[++t1] = node[i];//第k大!!先减再复制!!
}
else {
if(node[i].w <= mid) p1[++t1] = node[i];
else p2[++t2] = node[i], bit.ins(dfn[node[i].x], node[i].d);
}
}
for(int i = L; i <= R; ++i)
if(!node[i].type && node[i].w > mid)
bit.ins(dfn[node[i].x], -node[i].d);
for(int i = 1; i <= t1; ++i) node[L + i - 1] = p1[i];
for(int i = 1; i <= t2; ++i) node[L + t1 + i - 1] = p2[i];
erfn(L, L + t1 - 1, l, mid); erfn(L + t1, R, mid + 1, r);
}
int main() {
memset(head, -1, sizeof(head));
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
addnode(0, i, 0, a[i], 1, 0);
}
for(int i = 1, x, y; i < n; ++i){
scanf("%d%d", &x, &y);
addedge(x, y); addedge(y, x);
} dfs1(1, 0); dfs2(1, 1);
for(int i = 1, x, y, z; i <= m; ++i){
scanf("%d%d%d", &x, &y, &z); flag[i] = (bool)x;
if(x){
int len = dep[y] + dep[z] - 2 * dep[LCA(y, z)] + 1;
if(x > len) ans[i] = -1;
else addnode(i, y, z, x, 0, 1);
}
else addnode(i, y, 0, a[y], -1, 0), addnode(i, y, 0, z, 1, 0), a[y] = z, ans[i] = -1;
}
erfn(1, nsize, 0, inf);
for(int i = 1; i <= m; ++i)
if(flag[i]){
if(ans[i] == -1) printf("invalid request!\n");
else printf("%d\n", ans[i]);
}
//system("PAUSE");
return 0;
}
[CTSC2008]网络管理 [整体二分]的更多相关文章
- 【BZOJ1146】【CTSC2008】网络管理 [整体二分]
网络管理 Time Limit: 50 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司,在 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)
传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...
- [CTSC2008]网络管理(整体二分+树剖+树状数组)
一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...
- [CTSC2008]网络管理 [树剖+整体二分]
这题的复杂度可以到达惊人的\(\log^4\)据说还能跑过去(差点没吓死我 直接二分+树剖树套树(\(n \log^4 n\)) 一个\(\log\)也不少的4\(\log\) 但是我有个\(\log ...
- 【BZOJ1146】网络管理(整体二分)
[BZOJ1146]网络管理(整体二分) 题面 良心洛谷,有BZOJ权限题 题解 要看树套树的戳这里 毕竟是:智商不够数据结构来补 所以, 我们来当一回智商够的选手 听说主席树的题目大部分都可以整体二 ...
- bzoj 1146 网络管理Network (CDQ 整体二分 + 树刨)
题目传送门 题意:求树上路径可修改的第k大值是多少. 题解:CDQ整体二分+树刨. 每一个位置上的数都会有一段持续区间 根据CDQ拆的思维,可以将这个数拆成出现的时间点和消失的时间点. 然后通过整体二 ...
- Luogu4175:[CTSC2008]网络管理Network
题面 Luogu4175:[CTSC2008]网络管理Network Sol 路径第\(k\)大 无解直接判断就好了 然后整体二分,加上树链剖分+树状数组统计 # include <bits/s ...
- 洛谷 P4175 [CTSC2008]网络管理 解题报告
P4175 [CTSC2008]网络管理 题目描述 带修改树上链的第\(k\)大 输入输出格式 输入格式: 第一行为两个整数\(N\)和\(Q\),分别表示路由器总数和询问的总数. 第二行有\(N\) ...
随机推荐
- .NET的未来-广州.NET俱乐部学生分会
偶然的一次机会,让我发现了在我们社区的微信群里潜藏着许多高校的学生,他们有的来自重点高校中山大学.华南理工,也有的来自普通高校的惠州学院.广州白云学院等. 因为相同的技术爱好使他们聚集在社区.相同的技 ...
- 关于Skyline沿对象画boundingbox的探讨
先来说说为什么要搞这个?项目中经常遇到的一个操作就是选定对象,以前都是通过Tint设置对象颜色来标识选定对象,但是随着图层中模型增多,模型色彩丰富,会出现选定色与对象颜色对比不明显的情况.因为看到Te ...
- Android 为TV端助力
记录两次事情: 第一个给view添加动画效果,需要保证view是可以获取焦点的 第二个给listview,GridView设置选择器 listselector时,要保证他的子item无背景,否则选择器 ...
- Android Studio遇到Failed to sync Gradle project错误时的解决办法
一 报错显示 Gradle sync failed: Unknown host 'd29vzk4ow07wi7.cloudfront.net'. You may need to adjust th ...
- Linux AIDE(文件完整性检测)
一.AIDE的概念 AIDE:Advanced Intrusion Detection Environment,是一款入侵检测工具,主要用途是检查文档的完整性.AIDE在本地构造了一个基准的数据库,一 ...
- SQLServer之修改FOREIGN KEY约束
使用SSMS数据库管理工具修改FOREIGN KEY约束 1.连接数据库,选择数据表->右键点击->选择设计(或者展开键,选择要修改的外键,右键点击,选择修改,后面修改步骤相同). 2.在 ...
- 多线程——multiprocess
先看个误打误撞的写的代码 import os import time import multiprocessing def func(): print('我是func函数1','现在的father进程 ...
- Nginx健康检查模块
在本小节我们介绍一个用于Nginx对后端UpStream集群节点健康状态检查的第三方模块:nginx_upstream_check_module(https://github.com/yaoweibi ...
- wps for linux显示系统缺失字体解决办法
1.下载字体库 链接: https://pan.baidu.com/s/1xil5_i9M53fM7EQNIt3Mcw 密码: jqnu 2.解压 sudo unzip wps_symbol_font ...
- Sqlserver查询死锁及杀死死锁的方法
-- 查询死锁 select request_session_id spid, OBJECT_NAME(resource_associated_entity_id) tableName from sy ...