POJ-2985(树状数组 + 并查集 + 二分)
2015-02-26 19:55
246 查看
题目:http://poj.org/problem?id=2985
这题考察了两个点呢,组合并用到了并查集,求第K大的数用到了树状数组,刚开始WA了几次,发现是在组合并之后仅仅update(*, -1)了一次,因为是删除了两个组增加了一个组,应该是update(*, -1)两次,不细心啊。。。
![](http://img.blog.csdn.net/20150226195501911?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdXV1b3VvdWxjeg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
这题考察了两个点呢,组合并用到了并查集,求第K大的数用到了树状数组,刚开始WA了几次,发现是在组合并之后仅仅update(*, -1)了一次,因为是删除了两个组增加了一个组,应该是update(*, -1)两次,不细心啊。。。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX 200005 int N, M, G; int father[MAX] = {0}; //father[i]表示i所在group的首脑 int member[MAX] = {0}; //member[i]表示以i为首的group有多少个member int group[MAX] = {0}; //group[i]表示成员有[i-lowbit(i)+1, i]个的group有多少个, inline int lowbit(int x){ return x & -x; } void update(int x, int v){ for(; x <= N; x += lowbit(x)){ group[x] += v; } } int sum(int x) { int tot = 0; for(; x; x -= lowbit(x)) tot += group[x]; return tot; } int query(int k) { int l = 0, r = N; while(l + 1 < r){ int m = (l + r) >> 1; if(sum(m) >= k) r = m; else l = m; } return r; } int find(int x){ return x != father[x] ? father[x] = find(father[x]) : x; } void join(int x, int y) { int fx = find(x), fy = find(y); if(fx == fy) return; if(member[fx] > member[fy]) swap(fx, fy); father[fx] = fy; update(member[fy], -1); member[fy] += member[fx]; update(member[fx], -1); member[fx] = 0; update(member[fy], 1); --G; } void init() { for(int i = 1; i <= N; ++i) father[i] = i; for(int i = 1; i <= N; ++i) member[i] = 1; G = N; memset(group + 1, 0, N * sizeof(int)); for(int i = 0; (1 << i) <= N; ++i) group[1 << i] = N; } int main() { int c, x, y; while(~scanf("%d%d", &N, &M)){ init(); while(M--){ scanf("%d%d", &c, &x); if(c) printf("%d\n", query(G - x + 1)); else{ scanf("%d", &y); join(x, y); } } } return 0; }
相关文章推荐
- POJ 2985 The k-th Largest Group 第k大数 Treap / 树状数组 + 并查集
- POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)
- 【树状数组求第k小+并查集】POJ 2985
- POJ-2892(树状数组 + 二分)
- 【POJ 2892】 Tunnel Warfare(树状数组+二分)
- POJ - 2182 D - Lost Cows 暴力//树状数组加二分
- POJ-2182 Lost Cows (二分 + 树状数组 或者平衡树)
- 树状数组从前往后求和,用来解第k大(或小)的数 poj 2985 The k-th Largest Group
- POJ 2892 Tunnel Warfare(树状数组+二分)
- poj 2892 Tunnel Warfare(树状数组+二分)
- poj 2892 Tunnel Warfare(树状数组+二分)
- 【poj 2104】K-th Number【整体二分+树状数组】
- POJ 2892 Tunnel Warfare (树状数组+二分)
- POJ 2104 K-th Number【整体二分 + 树状数组】
- POJ 2886 Who Gets the Most Candies?(树状数组+二分)
- POJ - 2886 Who Gets the Most Candies? 树状数组 + 二分 + 反素数
- POJ 题目2182 Lost Cows(树状数组+二分)
- POJ 2828 Buy Tickets(树状数组+二分)
- Poj 2985 树状数组求第k大
- 树状数组从前往后求和,用来解第k大(或小)的数 poj 2985 The k-th Largest Group