[BZOJ 1146] [CTSC2008]网络管理Network
来源:互联网 发布:广联达软件价格 编辑:程序博客网 时间:2024/05/16 14:35
http://www.lydsy.com/JudgeOnline/problem.php?id=1146
树巨结垢限时训练系列。
选择了 二分 树剖 线段树 Treap 的写法。
1小时写完 15分钟调好…..
感觉写的已经比较漂亮了,可以作为树上单点修改 K 大的一份模版
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <vector>#define rep(i, x, y) for (int i = (x), _ = (y); i <= _; ++i)#define down(i, x, y) for (int i = (x), _ = (y); i >= _; --i)#define x first#define y second#define LX_JUDGEusing namespace std;typedef long long LL;template<typename T> inline void up_max(T & x, T y) { x < y ? x = y : 0; }template<typename T> inline void up_min(T & x, T y) { x > y ? x = y : 0; }template<typename T>inline void read(T & x){ char c; while ((c = getchar()) < '0' || c > '9') ; for (x = c - '0'; (c = getchar()) >= '0' && c <= '9'; x = x * 10 + c - '0') ;}const int N = 8e4 + 10;namespace Treap{ struct node { node * ch[2]; int val, size, r; inline void push_up() { size = (ch[0] ? ch[0]->size : 0) + (ch[1] ? ch[1]->size : 0) + 1; } } pool_node[N * 20], *pool_top = pool_node; node * root = 0; void rotate(node *&o, int d) { node * u = o->ch[d]; o->ch[d] = u->ch[d ^ 1]; u->ch[d ^ 1] = o; o->push_up(); u->push_up(); o = u; } void insert(node *& o, node * u) { if (!o) { o = u; o->ch[0] = o->ch[1] = 0; o->size = 1; return ; } int d = o->val < u->val; ++o->size; insert(o->ch[d], u); if (o->ch[d]->r > o->r) rotate(o, d); } node * recent; void remove(node *& o, int val) { if (o->val == val) { if (!o->ch[0]) { recent = o; o = o->ch[1]; } else if (!o->ch[1]) { recent = o; o = o->ch[0]; } else { int d = o->ch[1]->r > o->ch[0]->r; rotate(o, d); --o->size; remove(o->ch[d ^ 1], val); } } else { int d = o->val < val; --o->size; remove(o->ch[d], val); } } void modify(node *& R, int val, int to) { remove(R, val); recent->val = to; insert(R, recent); } node * build(int * a, int n) { static node * stk[N]; static int top = 0; rep(i, 0, n - 1) { node * o = ++pool_top, *last = 0; o->val = a[i]; o->r = rand(); while (top && stk[top]->r < o->r) stk[top]->push_up(), last = stk[top--]; if (top) stk[top]->ch[1] = o; o->ch[0] = last; stk[++top] = o; } while (top) stk[top--]->push_up(); return stk[1]; } int getRank(node *o, int val) { int ret = 0; while (o) { int d = o->val < val; if (!d) ret += (o->ch[1] ? o->ch[1]->size : 0) + 1; o = o->ch[d]; } return ret; } int query(const vector<node * > & q, int K) { int l = 1, r = 1e8; while (l <= r) { int mid = (l + r) >> 1, tmp = 0; rep (i, 0, q.size() - 1) tmp += getRank(q[i], mid); tmp >= K ? l = mid + 1 : r = mid - 1; } return r; }}int mem_tmp[N], mem[N];namespace SegmentTree{ struct node { node * ch[2]; int l, r; Treap::node * root; }; node * newnode() { static node pool_node[N * 2], * pool_top = pool_node; return ++pool_top; } void build(node *&o, int l, int r) { o = newnode(); o->l = l, o->r = r; if (l == r) { o->root = Treap::build(mem + l, 1); return ; } int mid = (l + r) >> 1; build(o->ch[0], l, mid); build(o->ch[1], mid + 1, r); int tl = l, tr = mid + 1; for (int i = l; i <= r; ++i) { if (tr > r || (tl <= mid && mem[tl] < mem[tr])) mem_tmp[i] = mem[tl++]; else mem_tmp[i] = mem[tr++]; } memcpy(mem + l, mem_tmp + l, sizeof(int) * (r - l + 1)); o->root = Treap::build(mem + l, r - l + 1); } void split(node *o, int l, int r, vector<Treap::node * > & q) { if (l <= o->l && o->r <= r) { q.push_back(o->root); return ; } int mid = (o->l + o->r) >> 1; if (mid >= r) split(o->ch[0], l, r, q); else if (mid < l) split(o->ch[1], l, r, q); else split(o->ch[0], l, r, q), split(o->ch[1], l, r, q); } int modify(node *o, int pos, int val) { if (o->l == o->r) { int ret = o->root->val; Treap::modify(o->root, ret, val); return ret; } int ret = modify(o->ch[((o->l + o->r) >> 1) < pos], pos, val); Treap::modify(o->root, ret, val); return ret; }}SegmentTree::node * H[N];struct edge{ int to; edge *n;} pool_edge[N * 2], *head[N], *cur = pool_edge;inline void addEdge(int x, int y){ cur->to = y, cur->n = head[x], head[x] = cur++; cur->to = x, cur->n = head[y], head[y] = cur++;}struct treenode{ int size, Hson, deep, fa, top, dfn;}t[N];void init_dfs(int x){ t[x].size = 1; for (edge *p = head[x]; p; p = p->n) { int to = p->to; if (t[x].fa == to) continue ; t[to].fa = x; t[to].deep = t[x].deep + 1; init_dfs(to); t[x].size += t[to].size; if (t[to].size > t[t[x].Hson].size) t[x].Hson = to; }}int ival[N], tim;void calc_dfs(int x, int tt){ t[x].dfn = ++tim; t[x].top = tt; mem[tim] = ival[x]; if (t[x].Hson) { calc_dfs(t[x].Hson, tt); for (edge *p = head[x]; p; p = p->n) if (t[x].fa != p->to && t[x].Hson != p->to) calc_dfs(p->to, p->to); } else SegmentTree::build(H[t[x].top], t[t[x].top].dfn, t[x].dfn);}int solve(int x, int y, int K){ using SegmentTree::split; static vector<Treap::node *> Q; Q.clear(); int cnt = 0; while (t[x].top != t[y].top) { if (t[t[x].top].deep < t[t[y].top].deep) swap(x, y); split(H[t[x].top], t[t[x].top].dfn, t[x].dfn, Q); cnt += t[x].dfn - t[t[x].top].dfn + 1; x = t[t[x].top].fa; } if (t[x].deep > t[y].deep) swap(x, y); cnt += t[y].dfn - t[x].dfn + 1; split(H[t[x].top], t[x].dfn, t[y].dfn, Q); return cnt >= K ? Treap::query(Q, K) : -1;}int main(){#ifdef LX_JUDGE freopen("in.txt", "r", stdin);#endif int n, m; read(n), read(m); rep (i, 1, n) read(ival[i]); for (int i = 1, x, y; i < n; ++i) { read(x), read(y); addEdge(x, y); } init_dfs(1); calc_dfs(1, 1); int opt, x, y; while (m--) { read(opt); read(x), read(y); if (opt == 0) SegmentTree::modify(H[t[x].top], t[x].dfn, y); else { x = solve(x, y, opt); x > 0 ? printf("%d\n", x) : puts("invalid request!"); } } return 0;}
0 0
- 【BZOJ 1146】 [CTSC2008]网络管理Network
- 【树链剖分】【bzoj 1146】: [CTSC2008]网络管理Network
- bzoj 1146: [CTSC2008]网络管理Network
- [BZOJ 1146] [CTSC2008]网络管理Network
- BZOJ 1146 [CTSC2008]网络管理Network
- BZOJ 1146: [CTSC2008]网络管理Network
- [主席树 树状数组套权值线段树] BZOJ 1146 [CTSC2008]网络管理Network
- BZOJ 1146: [CTSC2008]网络管理Network 【树上带修改主席树】
- BZOJ1146: [CTSC2008]网络管理Network
- 【bzoj1146】[CTSC2008]网络管理Network
- [BZOJ1146][CTSC2008]网络管理Network
- bzoj1146: [CTSC2008]网络管理Network
- 【bzoj1146】 [CTSC2008]网络管理Network
- 1146: [CTSC2008]网络管理Network 树套树,二分,树剖
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分 树状数组套主席树/线段树套平衡树
- bzoj1146: [CTSC2008]网络管理Network 树套树
- BZOJ1146——[CTSC2008]网络管理Network
- 【BZOJ】【P1146】【CTSC2008】【网络管理Network】【题解】【树链剖分+线段树套平衡树】
- Android 缓存工具DiskLruCache用法
- sdut 3262 Circle of Friends tarjan
- C++Builder将对话框封装进Dll
- DIV+CSS 网页兼容性问题(IE6 IE7 IE8 IE9 火狐 chorm)
- JAVA——Date类、Calendar类
- [BZOJ 1146] [CTSC2008]网络管理Network
- 新来的
- 第十三周项目-阅读程序-2
- Android电源管理-休眠简要分析
- Android应用性能测试(CPU跟内存的性能)
- Vysor - 通过 USB 数据线在电脑上远程控制 Android 手机平板/同步显示画面的神器
- cygwin下如何清屏(clear screan)
- Win10-64bit安装MySQL5.7,解决Access denied for user 'root'@'localhost' 问题
- 接口测试总结