题面

bzoj

luogu

所有事件按时间排序

按值划分下放

把每一个修改

改成一个删除一个插入

对于一个查询

直接查这个段区间有多少合法点

如果查询值大于等于目标值 进入左区间

如果一个查询无解

那么它要求第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]网络管理 [整体二分]的更多相关文章

  1. 【BZOJ1146】【CTSC2008】网络管理 [整体二分]

    网络管理 Time Limit: 50 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司,在 ...

  2. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  3. 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)

    传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...

  4. [CTSC2008]网络管理(整体二分+树剖+树状数组)

    一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...

  5. [CTSC2008]网络管理 [树剖+整体二分]

    这题的复杂度可以到达惊人的\(\log^4\)据说还能跑过去(差点没吓死我 直接二分+树剖树套树(\(n \log^4 n\)) 一个\(\log\)也不少的4\(\log\) 但是我有个\(\log ...

  6. 【BZOJ1146】网络管理(整体二分)

    [BZOJ1146]网络管理(整体二分) 题面 良心洛谷,有BZOJ权限题 题解 要看树套树的戳这里 毕竟是:智商不够数据结构来补 所以, 我们来当一回智商够的选手 听说主席树的题目大部分都可以整体二 ...

  7. bzoj 1146 网络管理Network (CDQ 整体二分 + 树刨)

    题目传送门 题意:求树上路径可修改的第k大值是多少. 题解:CDQ整体二分+树刨. 每一个位置上的数都会有一段持续区间 根据CDQ拆的思维,可以将这个数拆成出现的时间点和消失的时间点. 然后通过整体二 ...

  8. Luogu4175:[CTSC2008]网络管理Network

    题面 Luogu4175:[CTSC2008]网络管理Network Sol 路径第\(k\)大 无解直接判断就好了 然后整体二分,加上树链剖分+树状数组统计 # include <bits/s ...

  9. 洛谷 P4175 [CTSC2008]网络管理 解题报告

    P4175 [CTSC2008]网络管理 题目描述 带修改树上链的第\(k\)大 输入输出格式 输入格式: 第一行为两个整数\(N\)和\(Q\),分别表示路由器总数和询问的总数. 第二行有\(N\) ...

随机推荐

  1. PHP实现开心消消乐的算法示例

    本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述:      1.在一个8*8的矩阵方格中随机 ...

  2. matlab练习程序(对应点集配准的四元数法)

    这个算是ICP算法中的一个关键步骤,单独拿出来看一下. 算法流程如下: 1.首先得到同名点集P和X. 2.计算P和X的均值up和ux. 3.由P和X构造协方差矩阵sigma. 4.由协方差矩阵sigm ...

  3. SQL Server 数据库调整表中列的顺序操作

    SQL Server 数据库中表一旦创建,我们不建议擅自调整列的顺序,特别是对应的应用系统已经上线,因为部分开发人员,不一定在代码中指明了列名.表是否可以调整列的顺序,其实可以自主设置,我们建议在安装 ...

  4. python 实例四

    https://www.cnblogs.com/evablogs/p/6754981.html 题目:输入某年某月某日,判断这一天是这一年的第几天? 程序分析: 月份天数: 月份 天数 2 平年28天 ...

  5. Bootstrap -- 文本,背景,其他样式

    Bootstrap -- 文本,背景,其他样式 1. 文本样式:展示了不同的文本颜色 使用文本样式: <!DOCTYPE html> <html> <head> & ...

  6. SQLServer数据库差异备份

    差异备份 (differential backup)定义 一种数据备份,基于完整数据库或部分数据库或一组数据文件或文件组(差异基准)的最新完整备份,并且仅包含自确定差异基准以来发生更改的数据. 使用S ...

  7. Python基础——6面向对象编程

    类和实例 类是抽象的模版,例如汽车:而实例则是拥有相同方法的类的实现,例如汽车里面有大众.宝马.奔驰等等,这些车都能在地面上跑,但是它们的具体数据可以不一样. calss Student(object ...

  8. 面向对象_classmethod_staticmethod

    classmethod:类方法 主要用于改变静态属性 class Fruit_price: __discount= 1 def __init__(self,original_price): self. ...

  9. JavaScript面向对象—基本数据类型和引用数据类型的区别和变量及作用域(函数和变量)

    基本类型和引用类型的值 ECMAScript 变量可能包含两种不同的数据类型的值:基本类型值和引用类型值. 基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置. 而引用 ...

  10. SQL 增删改语句

    阅读目录 一:插入数据 二:更新数据 三:删除数据 回到顶部 一:插入数据 把数据插入表中的最简单方法是使用基本的 INSERT 语法.它的要求是需要我们指定表名和插入到新行中的值. 1.1 插入完整 ...