[BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network
试题描述
输入
输出
输入示例
输出示例
invalid request!
数据规模及约定
见“输入”
题解
树链剖分套线段树套 treap + 二分。4 个 log 爽上天。
本来打了个 1A 的代码,发现它让求第 k “大”而非第 k “小”,而样例给的都是中位数!!!!于是拿黄学长的代码调了半天总是有错发现他数组开小了(那居然还能过!)。我调啊调啊调,改啊改啊改。。。一个上午过去,终于 A 掉了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 80010
#define maxm 160010
#define maxnode 5440010
struct Node {
int v, r, siz;
Node() {}
Node(int _, int __): v(_), r(__) {}
} ns[maxnode];
int ToT, fa[maxnode], ch[2][maxnode];
void maintain(int o) {
if(!o) return ;
ns[o].siz = 1;
for(int i = 0; i < 2; i++) if(ch[i][o])
ns[o].siz += ns[ch[i][o]].siz;
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[ch[1][z]==y][z] = u;
if(ch[1][y] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[r][u]] = y;
ch[l][y] = ch[r][u]; ch[r][u] = y;
maintain(y); maintain(u);
return ;
}
void insert(int& o, int v) {
if(!o) {
ns[o = ++ToT] = Node(v, rand());
return maintain(o);
}
bool d = v > ns[o].v;
insert(ch[d][o], v); fa[ch[d][o]] = o;
if(ns[ch[d][o]].r > ns[o].r) {
int t = ch[d][o];
rotate(t); o = t;
}
return maintain(o);
}
void del(int& o, int v) {
if(!o) return ;
if(ns[o].v == v) {
if(!ch[0][o] && !ch[1][o]) o = 0;
else if(!ch[0][o]) {
int t = ch[1][o]; fa[t] = fa[o]; o = t;
}
else if(!ch[1][o]) {
int t = ch[0][o]; fa[t] = fa[o]; o = t;
}
else {
bool d = ns[ch[1][o]].r > ns[ch[0][o]].r;
int t = ch[d][o]; rotate(t); o = t;
del(ch[d^1][o], v);
}
}
else {
bool d = v > ns[o].v;
del(ch[d][o], v);
}
return maintain(o);
}
int Find(int o, int v) {
if(!o) return 0;
int rs = ch[1][o] ? ns[ch[1][o]].siz : 0;
if(v <= ns[o].v) return rs + 1 + Find(ch[0][o], v);
return Find(ch[1][o], v);
} int rt[maxn<<2], ql, qr, val[maxn];
void add(int L, int R, int o) {
insert(rt[o], val[ql]);
if(L == R) return ;
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) add(L, M, lc);
else add(M+1, R, rc);
return ;
}
void update(int L, int R, int o, int x) {
del(rt[o], val[ql]); insert(rt[o], x);
if(L == R) return ;
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) update(L, M, lc, x);
else update(M+1, R, rc, x);
return ;
}
int query(int L, int R, int o, int x) {
if(ql <= L && R <= qr) return Find(rt[o], x);
int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = 0;
if(ql <= M) ans += query(L, M, lc, x);
if(qr > M) ans += query(M+1, R, rc, x);
return ans;
} int n, m, head[maxn], next[maxm], to[maxm], inv[maxn];
void AddEdge(int a, int b) {
to[++m] = b; next[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; next[m] = head[a]; head[a] = m;
return ;
}
int pa[maxn], son[maxn], dep[maxn], siz[maxn], top[maxn], W[maxn], ww;
void build(int u) {
siz[u] = 1;
for(int e = head[u]; e; e = next[e]) if(to[e] != pa[u]) {
pa[to[e]] = u; dep[to[e]] = dep[u] + 1;
build(to[e]);
siz[u] += siz[to[e]];
if(!son[u] || siz[son[u]] < siz[to[e]]) son[u] = to[e];
}
return ;
}
void gett(int u, int tp) {
W[u] = ++ww; top[u] = tp;
if(son[u]) gett(son[u], tp);
for(int e = head[u]; e; e = next[e]) if(to[e] != pa[u] && to[e] != son[u])
gett(to[e], to[e]);
return ;
}
int que(int a, int b, int x) {
int f1 = top[a], f2 = top[b], ans = 0;
while(f1 != f2) {
if(dep[f1] < dep[f2]) swap(f1, f2), swap(a, b);
ql = W[f1]; qr = W[a];
ans += query(1, n, 1, x);
a = pa[f1]; f1 = top[a];
}
if(dep[a] < dep[b]) swap(a, b);
ql = W[b]; qr = W[a];
return ans + query(1, n, 1, x);
} int main() {
n = read(); int q = read();
for(int i = 1; i <= n; i++) inv[i] = read() + 1;
for(int i = 1; i < n; i++) {
int a = read(), b = read();
AddEdge(a, b);
}
build(1); gett(1, 1);
for(int i = 1; i <= n; i++) val[W[i]] = inv[i];
for(int i = 1; i <= n; i++) ql = i, add(1, n, 1);
while(q--) {
int k = read(), a = read(), b = read();
if(!k) ql = W[a], update(1, n, 1, b + 1), val[W[a]] = b + 1;
else {
int l = 0, r = 100000002;
while(r - l > 1) {
int mid = l + r >> 1;
if(que(a, b, mid) < k) r = mid; else l = mid;
}
if(l) printf("%d\n", l - 1); else puts("invalid request!");
}
} return 0;
}
代码是挺短的。。。
[BZOJ1146][CTSC2008]网络管理Network的更多相关文章
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- BZOJ1146——[CTSC2008]网络管理Network
1.题目大意:就是在动态的树上路径权值第k大. 2.分析:这个就是树链剖分+树套树 #include <cstdio> #include <cstdlib> #include ...
- 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)
传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...
- 【树上莫队】【带修莫队】【权值分块】bzoj1146 [CTSC2008]网络管理Network
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...
- 【树链剖分】【函数式权值分块】bzoj1146 [CTSC2008]网络管理Network
裸题,直接上.复杂度O(n*sqrt(n)*log(n)). //Num[i]表示树中的点i在函数式权值分块中对应的点 //Map[i]表示函数式权值分块中的点i在树中对应的点 #include< ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
随机推荐
- Path Sum II
Path Sum II Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals ...
- AppBox升级进行时 - 扁平化的权限设计
AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. AppBox v2.0中的权限实现 AppBox v2.0中权限管理中涉及三个 ...
- Spark在Ubuntu中搭建开发环境
一.在Windows7中安装Ubuntu双系统 工具/原料 windows7 64位 ubuntu 16.04 32位 UltraISO最新版(用来将镜像文件烤到U盘中) 空U盘(若有文件,请先备 ...
- 【jQuery】scroll 滚动到顶部
Jquery 实现页面滚动到顶端 $(document).ready(function () { // 滚动窗口来判断按钮显示或隐藏 $(window).scroll(function () { // ...
- C#字符串操作 取文本左边 取文本右边 取文本中间 取文本中间到List集合 指定文本倒序
/// <summary> /// 取文本左边内容 /// </summary> /// <param name="str">文本</pa ...
- css实现了hover显示title的效果
<div data-title="hello, world">hello...</div> <style> div { position: re ...
- 每个程序员都会的35个jQuery小技巧!
1. 禁止右键点击$(document).ready(function(){ $(document).bind("contextmenu",function(e){ return ...
- Mysql索引PRIMARY、NORMAL、UNIQUE、FULLTEXT 区别和使用场合
索引 数据库的索引就像一本书的目录,能够加快数据库的查询速度. MYSQL索引有四种PRIMARY.INDEX.UNIQUE.FULLTEXT, 其中PRIMARY.INDEX.UNIQUE是一类,F ...
- C#接口和抽象类的区别
大家都容易把这两者搞混,我也一样,在听李建忠老师的设计模式时,他也老把抽象类说成接口,弄的我就更糊涂了,所以找了些网上的资料. 一.抽象类: 抽象类是特殊的类,只是不能被实例化:除 ...
- 用 CSS 隐藏页面元素
用 CSS 隐藏页面元素有许多种方法.你可以将 opacity 设为 0 将 visibility 设为 hidden 将 display 设为 none 将 position 设为 absolute ...