luogu解题报告:HNOI2012永无乡
来源:互联网 发布:开淘宝店前期如何推广 编辑:程序博客网 时间:2024/05/29 15:32
https://www.luogu.org/problem/show?pid=3224
启发式合并+平衡树+并查集…
复杂度
Splay一次写过然而后面各种跪..调试能力捉急…估计是WC2017课前助眠音乐听太多了…
#include <bits/stdc++.h>using namespace std;const int N = 100005;struct node { int dat, siz, id; int chl[2], fa;} tree[N*30];int top = 0;class splay_tree { int root; int new_node(int dat, int fa) { //if (dat < 0) printf("!!%d-%d!!\n", dat, tree[fa].id); return tree[++top].dat = dat, tree[top].fa = fa, tree[top].siz = 1, tree[top].chl[0] = tree[top].chl[1] = 0, top; } void update(int nd) { if (nd) tree[nd].siz = tree[tree[nd].chl[0]].siz + tree[tree[nd].chl[1]].siz + 1; } void zig(int nd) { if (!nd || nd == root) return; int p = tree[nd].fa, tp = tree[p].chl[0] != nd, son = tree[nd].chl[tp^1]; int g = tree[p].fa, tg = tree[g].chl[0] != p; tree[son].fa = p, tree[p].chl[tp] = son; tree[nd].chl[tp^1] = p, tree[p].fa = nd; tree[nd].fa = g; if (g) tree[g].chl[tg] = nd; else root = nd; update(p), update(nd); } void splay(int nd) { while (nd != root && tree[tree[nd].fa].fa) { int p = tree[nd].fa, g = tree[p].fa; int tp = tree[p].chl[0] != nd, tg = tree[g].chl[0] != p; if (tp == tg) zig(p), zig(nd); else zig(nd), zig(nd); } if (tree[nd].fa) zig(nd); } void insert(int &nd, int dat, int id, int fa = 0) { if (nd == 0) nd = new_node(dat, fa), tree[nd].id = id, splay(nd); else { //tree[nd].siz++; if (tree[nd].dat <= dat) insert(tree[nd].chl[1], dat, id, nd); else insert(tree[nd].chl[0], dat, id, nd); update(nd); } } void dfs(int nd, int tab = 0) { if (!nd) return; for (int i = 1; i <= tab; i++) putchar(' '); printf("id = %d, dat = %d, siz = %d\n", tree[nd].id, tree[nd].dat, tree[nd].siz); dfs(tree[nd].chl[0], tab+2); dfs(tree[nd].chl[1], tab+2); }public: splay_tree():root(0) {} inline void push(int dat, int id) { insert(root, dat, id); } inline int& get_root() { return root; } int find_kth(int k) { //cout << tree[root].id << " " << k << " " << tree[root].siz << endl; if (k <= 0 || k > tree[root].siz) return 0; k--; int nd = root; while (nd > 0 && k >= 0) { //cout << tree[nd].id << " " << k << endl; //cout << tree[1026].id << endl; if (tree[tree[nd].chl[0]].siz == k) return nd; if (tree[tree[nd].chl[0]].siz > k) nd = tree[nd].chl[0]; else k -= tree[tree[nd].chl[0]].siz + 1, nd = tree[nd].chl[1]; } return 0; } void merge(int nd) { if (nd <= 0) return; //cout << nd << " " << tree[nd].dat << endl; push(tree[nd].dat, tree[nd].id); merge(tree[nd].chl[0]); merge(tree[nd].chl[1]); } void dfs() { dfs(root); }} f[N];int target[N];inline int findp(int i) { return target[i]?target[i] = findp(target[i]):i;}inline void link(int i, int j){ if (findp(i) != findp(j)) target[findp(i)] = findp(j); }void merge(int a, int b){ //cout << tree[f[a].get_root()].id << " f**k " << b << " " << findp(b) << " " << f[b].get_root() << " " << tree[f[b].get_root()].id << endl; if (f[a].get_root() <= 0 || f[b].get_root() <= 0) return; if (a != b) { if (tree[f[a].get_root()].siz < tree[f[b].get_root()].siz) f[b].merge(f[a].get_root()), f[a].get_root() = -1, link(a, b); else f[a].merge(f[b].get_root()), f[b].get_root() = -1, link(b, a); }}int n, m, q, dat;int a, b;char opt;void work(){ freopen("bzoj_2733.in", "r", stdin); freopen("bzoj_2733.out", "w", stdout); memset(target, 0, sizeof target); scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &dat), f[i].push(dat, i); for (int i = 1; i <= m; i++) { scanf("%d%d", &a, &b); merge(findp(a), findp(b)); } scanf("%d", &q); for (int i = 1; i <= q; i++) { scanf("\n%c %d %d", &opt, &a, &b); if (opt == 'Q') dat = f[findp(a)].find_kth(b), printf("%d\n", dat==0?-1:tree[dat].id); else if (opt == 'B') merge(findp(a), findp(b)); else if (opt == 'D') f[findp(a)].dfs(); else if (opt == 'L') cout << (findp(a) == findp(b)) << endl; }}int main(){ work(); return 0;}
0 0
- luogu解题报告:HNOI2012永无乡
- HNOI2012解题报告
- [HNOI2012]与非 解题报告
- [HNOI2012]矿场搭建 解题报告
- NOIp1998PJ/Luogu P1010 幂次方 解题报告
- Luogu T1125 why_always_I_like_素数 解题报告
- NOIp2015TG/Luogu P2661 信息传递 解题报告
- Luogu P1823 音乐会的等待 解题报告
- luogu解题报告:P3407散步【栈】【奇技淫巧】
- luogu解题报告:P3391文艺平衡树
- luogu解题报告:P2178[NOI2015]品酒大会
- 火星人(Luogu P1088)解题报告
- NOIp2010TG/Luogu P1514 引水入城 解题报告
- Luogu P1569 KC与龙珠 解题报告
- NOI2002/Luogu P1196 银河英雄传说 解题报告
- NOIp2012TG/Luogu P1082 同余方程 解题报告
- NOIp2009TG T2/Luogu P1072 Hankson的趣味题 解题报告
- luogu解题报告:P1119灾后重建【图论/最短路】
- 算法设计与分析题目练习三:骑士旅游问题(回溯算法)
- 【Hibernate】Component映射
- 超详细图文讲解android studio导入第三方类库的方法
- 求链表中环的入口点
- 搜索-状态空间搜索
- luogu解题报告:HNOI2012永无乡
- sqlite应用1
- HTML标签之程序标签
- IO流_IO流概述及分类
- Linux下一个简单守护进程的实现 (Daemon)
- [stackoverflow翻译] “yield” 关键字有什么用?what-does-the-yield-keyword-do
- tegra_multimedia_api里的README
- sql语句中order by、group by和having的区别
- java 实例化PortableRemoteObject笔记