BZOJ1146——[CTSC2008]网络管理Network
1、题目大意:就是在动态的树上路径权值第k大。
2、分析:这个就是树链剖分+树套树
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; #define M 1000000 int Height[M], Top[M], value[M], num[M], Size[M], Fa[M]; int ST_tot, tot; int son[M], head[M], Next[M]; int n, m; struct Node{ Node *ch[2]; int cnt, num, r, v; bool operator < (const Node& rhs) const{ return r < rhs.r; } int cmp(int x){ if(x == v) return -1; if(x < v) return 0; return 1; } void maintain(){ cnt = num; if(ch[0]) cnt += ch[0] -> cnt; if(ch[1]) cnt += ch[1] -> cnt; } } *root[2 * M], ft[5 * M]; int treap_tot; inline void treap_rotate(Node* &o, int d){ Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o; o -> maintain(); k -> maintain(); o = k; return; } inline void treap_insert(Node* &o, int x){ if(o == NULL){ o = &ft[treap_tot ++]; o -> ch[0] = o -> ch[1] = NULL; o -> cnt = o -> num = 1; o -> v = x; o -> r = rand(); } else{ int d = o -> cmp(x); if(d == -1){ o -> num ++; } else{ treap_insert(o -> ch[d], x); if(o < o -> ch[d]) treap_rotate(o, d ^ 1); } } o -> maintain(); } inline void treap_remove(Node* &o, int x){ int d = o -> cmp(x); if(d == -1){ if(o -> num > 1) o -> num --; else if(o -> ch[0] == NULL) o = o -> ch[1]; else if(o -> ch[1] == NULL) o = o -> ch[0]; else { int d2; if(o -> ch[0] > o -> ch[1]) d2 = 1; else d2 = 0; treap_rotate(o, d2); treap_remove(o -> ch[d2], x); } } else treap_remove(o -> ch[d], x); if(o) o -> maintain(); } inline int treap_lessk(Node* &o, int k){ if(o == NULL) return 0; int d = o -> cmp(k); if(d == -1){ int ret = 0; if(o -> ch[0]) ret += o -> ch[0] -> cnt; return ret; } else if(d == 0){ return treap_lessk(o -> ch[0], k); } else{ int ss = o -> num; if(o -> ch[0]) ss += o -> ch[0] -> cnt; return treap_lessk(o -> ch[1], k) + ss; } } inline void init(){ Top[1] = 1; memset(head, -1, sizeof(head)); tot = ST_tot = 0; } inline void add(int l, int r, int o, int x, int y, int z){ if(y != -1) treap_remove(root[o], y); treap_insert(root[o], z); if(l == r) { return; } int mid = (l + r) / 2; if(x <= mid) add(l, mid, 2 * o, x, y, z); else add(mid + 1, r, 2 * o + 1, x, y, z); } inline int query(int l, int r, int o, int x, int y, int z){ if(x <= l && r <= y) return root[o] -> cnt - treap_lessk(root[o], z); int ret = 0, mid = (l + r) / 2; if(x <= mid) ret += query(l, mid, 2 * o, x, y, z); if(y > mid) ret += query(mid + 1, r, 2 * o + 1, x, y, z); return ret; } inline void insert(int x, int y){ tot ++; son[tot] = y; Next[tot] = head[x]; head[x] = tot; } inline void dfs1(int x, int fa, int height){ Fa[x] = fa; Height[x] = height; Size[x] = 1; for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){ dfs1(son[i], x, height + 1); Size[x] += Size[son[i]]; } } inline void dfs2(int x, int fa){ ++ ST_tot; num[x] = ST_tot; add(1, n, 1, ST_tot, -1, value[x]); int o = 0, ss = 0; for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){ if(Size[son[i]] > ss){ ss = Size[son[i]]; o = i; } } if(o != 0){ Top[son[o]] = Top[x]; dfs2(son[o], x); } for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa && o != i){ Top[son[i]] = son[i]; dfs2(son[i], x); } } inline void real_add(int x, int y){ add(1, n, 1, num[x], value[x], y); value[x] = y; } inline int check(int x, int y, int k){ int ret = 0; while(Top[x] != Top[y]){ if(Height[Top[x]] < Height[Top[y]]) swap(x, y); ret += query(1, n, 1, num[Top[x]], num[x], k); x = Fa[Top[x]]; } if(Height[x] < Height[y]) swap(x, y); ret += query(1, n, 1, num[y], num[x], k); return ret; } inline int real_query(int x, int y, int k){ int l = -1, r = 100000000; while(l < r){ int mid = (l + r) / 2; if(mid == l) mid ++; if(check(x, y, mid) >= k) l = mid; else r = mid - 1; } if(l == -1) return -1; return l; } int main(){ scanf("%d%d", &n, &m); init(); for(int i = 1; i <= n; i ++) scanf("%d", &value[i]); for(int i = 1; i < n; i ++){ int x, y; scanf("%d%d", &x, &y); insert(x, y); insert(y, x); } dfs1(1, 0, 1); dfs2(1, 0); for(int i = 1; i <= m; i ++){ int k, x, y; scanf("%d%d%d", &k, &x, &y); if(k == 0){ real_add(x, y); } else if(k > 0){ int qq = real_query(x, y, k); if(qq == -1){ printf("invalid request!\n"); } else{ printf("%d\n", qq); } } } return 0; }
BZOJ1146——[CTSC2008]网络管理Network的更多相关文章
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- 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 ...
随机推荐
- 【原】requirejs学习笔记
随着JS越来越庞大,已经不仅仅是以前复制粘贴做特效的时代了,JS越来越偏向于业务逻辑与应用.JS在web开发中占有越来越重要的地位. 由于JS代码庞大,文件数目多,传统的使用<script sr ...
- MYSQL select查询练习题
10. 查询Score表中的最高分的学生学号和课程号.(子查询或者排序) select sno,cno from score where degree=(select max(degree) from ...
- WinForm------GridControl控件中使用SearchLookUpEdit控件的方法
1.在数据库添加两张表,拥有主外键关系 主键表: 外键表: 2.往工具栏里拖出GridCont控件,并增加相应的列,这里对"省份"进行修改,"FileName" ...
- 才知道创建数据表的后面int(M)的m居然和存储大小没有关系
之前一直以为,后面m代表有几个字节 MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MyS ...
- ecshop修改注册、增加手机
1.去掉“用户名”注册 a.去掉提交 user_passport.dwt页面去掉 <input name="username" type="text" s ...
- Autofac和DynamicProxy2搭配实现Aop动手训练
http://www.cnblogs.com/zhengwl/p/5433181.html Aop含义:aspect-oriented programming 实现工具介绍 Autofac是一个比较流 ...
- rpm 命令
这些事rpm的常用参数!!! 你可以在linux下man 一下rpm就知道了!!! 不过是英文的,不然你可以百度一下rpm就知道了额!!! 下面我帮你贴几个!!!!rpm 常用命令1.安装一个包 # ...
- php二维数组排序的处理
一维数组排序可以使用asort.ksort等一些方法进程排序,相对来说比较简单.二维数组的排序怎么实现呢?使用array_multisort和usort可以实现 例如像下面的数组: 代码如下: ...
- [Asp.net mvc]jquery.form.js无刷新上传
写在前面 最近在自己的网盘项目中想用ajax.beginform的方式做无刷新的操作,提交表单什么的都可以,但针对文件上传,就是个鸡肋.在网上查找了发现很多人都遇到了这个问题,大部分都推荐使用jque ...
- 【转】如何确定Kafka的分区数、key和consumer线程数
文章来源:http://www.cnblogs.com/huxi2b/p/4583249.html -------------------------------------------------- ...