poj 2985 The k-th Largest Group (并查集x全局动态第k大)
来源:互联网 发布:梦幻西游物价软件 编辑:程序博客网 时间:2024/05/22 10:54
题意:
。。。
思路:
用一个数据结构来存所有树的大小,合并操作先消去旧的再插入新的大小。
可以用 treap, BIT等等。。
这里有个树状数组
const int N = 200000 + 5;typedef long long LL;namespace Treap { static const int MaxNode = N; int root, nodes, key[MaxNode], fix[MaxNode], ch[MaxNode][2], cnt[MaxNode], siz[MaxNode]; void init() { root = 0; nodes = 1; fix[0] = INT_MAX; siz[0] = 0; } inline void update(int x) { siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x]; } void rot(int& x, int t) { int y = ch[x][t]; ch[x][t] = ch[y][1^t]; ch[y][1^t] = x; update(x); update(y); x = y; } void insert(int& x, int k) { if ( x ) { if ( key[x] == k ) { ++ cnt[x]; } else { int t = key[x] < k; insert(ch[x][t], k); if ( fix[ch[x][t]] < fix[x] ) { rot(x, t); } } } else { x = nodes ++; key[x] = k; cnt[x] = 1; fix[x] = rand(); ch[x][0] = ch[x][1] = 0; } update(x); } void erase(int& x, int k) { if ( key[x] == k ) { if ( cnt[x] > 1 ) { -- cnt[x]; } else { if ( !ch[x][0] && !ch[x][1] ) { x = 0; return; } else { int t = fix[ch[x][0]] > fix[ch[x][1]]; rot(x, t); erase(ch[x][1^t], k); } } } else { int t = key[x] < k; if ( ch[x][t] ) erase(ch[x][t], k); } update(x); } int count(int x, int k) { if ( x ) { if ( key[x] == k ) return cnt[x]; else return count( ch[x][key[x] < k], k ); } else return 0; } int getKth(int x, int k) { if ( k <= siz[ch[x][0]] ) return getKth(ch[x][0], k); k -= siz[ch[x][0]] + cnt[x]; if ( k <= 0 ) return key[x]; if ( k <= siz[ch[x][1]] ) return getKth(ch[x][1], k); else throw runtime_error("this is no kth element"); }};namespace UF { int pa[N], sz[N]; int Find(int x) { return x == pa[x] ? x : pa[x] = Find(pa[x]); } void init(int n) { Treap::init(); rep(i, 1, n) pa[i] = i, sz[i] = 1; rep(i, 1, n) Treap::insert(Treap::root, 1); } void Union(int x, int y) { int px = Find(x), py = Find(y); if ( px != py ) { Treap::erase(Treap::root, sz[px]); Treap::erase(Treap::root, sz[py]); sz[px] += sz[py]; pa[py] = px; Treap::insert(Treap::root, sz[px]); #if 0 cout << "after merge" << endl; int tot = tree.siz[tree.root]; rep(i, 1, tot) cout << tree.getKth(tree.root, i) << ' '; cout << endl; #endif // 1 } } int query(int k) { int tot = Treap::siz[Treap::root]; try { return Treap::getKth(Treap::root, tot + 1 - k); } catch ( exception& e ) { return 1; } //return tree.getKth(tree.root, tot + 1 - k); }}int main() {#ifdef _LOCA_ENV_ freopen("input.in", "r", stdin);#endif // _LOCA_ENV int n, m; scanf("%d%d", &n, &m); UF::init(n); int op, x, y; rep(i, 1, m) { scanf("%d", &op); if ( op == 0 ) { scanf("%d%d", &x, &y); //cout << "merge " << x << ' ' << y << endl; UF::Union(x, y); } else { scanf("%d", &x); //cout << "query " << x << endl; printf("%d\n", UF::query(x)); } } return 0;}
1 0
- poj 2985 The k-th Largest Group (并查集x全局动态第k大)
- poj 2985 The k-th Largest Group 并查集+树状数组求第k大
- POJ 2985 The k-th Largest Group 第k大数 Treap / 树状数组 + 并查集
- POJ 题目2985 The k-th Largest Group(线段树单点更新求第k大值,并查集)
- poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
- poj 2985 The k-th Largest Group/并查集+sbt
- poj 2985 The k-th Largest Group(线段树+并查集)
- poj 2985 The k-th Largest Group (Treap+并查集)
- Treap树(并查集 + 树堆)POJ —— 2985 The k-th Largest Group
- POJ 2985The k-th Largest Group 线段树求整体第K大
- POJ2985 The k-th Largest Group(treap+并查集)
- POJ 2985 The k-th Largest Group
- Poj 2985 The k-th Largest Group
- POJ-2985-The k-th Largest Group
- POJ 2985 The k-th Largest Group
- POJ 2985 The k-th Largest Group [并差集+treap]
- The k-th Largest (并查集+线段树)
- POJ 2985:The k-th Largest Group 树状数组求第K小的元素
- [Amazon ]去元音 get rid of vowels
- android不能直接连接mysql
- [Amazon]Given 2 numbers. Find if they are consecutive gray (grey) code sequences
- Eclipse使用Maven构建web项目二
- centos7安装vlc播放器
- poj 2985 The k-th Largest Group (并查集x全局动态第k大)
- 一些不错的网站
- LeetCode 题解(190): Implement Queue using Stacks
- Win7系统与它的Virtualbox中安装的Ubuntu14.04共享信息的几种方法
- C中的常见库文件说明
- regex
- 再django中应用selenium做测试
- 一个93年弱鸡程序员来到深圳深入简出
- POJ 1141 解题报告