poj2985The k-th Largest Group

来源:互联网 发布:fm 迭戈科斯塔数据 编辑:程序博客网 时间:2024/06/08 06:14

链接:http://poj.org/problem?id=2985

题意:初始给定n个元素个数为1的集合,然后给定m个操作,有两种操作:C=0时输入a,b表示将a,b所在的集合合并成一个集合,C=1时输入k表示询问当前所有集合中集合大小排序中的第k大的集合的size。

分析:集合合并直接用并查集维护就可以了,找第k大的话用树状数组找第k大就好了

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=200010;const int MAX=151;const int mod=100000000;const int MOD1=100000007;const int MOD2=100000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=1000000009;const ll INF=10000000010;typedef double db;typedef unsigned long long ull;int n,f[N],g[N],p[N];void add(int x,int y) {    for (;x<=n;x+=x&(-x)) p[x]+=y;}int sum(int x) {    int ret=0;    for (;x;x-=x&(-x)) ret+=p[x];    return ret;}int ask_k(int k) {    int i,w=0;    for (i=20;i>=0;i--)    if (w+(1<<i)<=n&&p[w+(1<<i)]<k) {        k-=p[w+(1<<i)];w+=1<<i;    }    return w+1;}int find_f(int x) {    return f[x]==x ? x:f[x]=find_f(f[x]);}int main(){    int a,b,c,k,i,m,tot;    scanf("%d%d", &n, &m);    memset(p,0,sizeof(p));    for (i=1;i<=n;i++) f[i]=i,g[i]=1;    add(1,n);tot=n;    while (m--) {        scanf("%d", &c);        if (!c) {            scanf("%d%d", &a, &b);            int fa=find_f(a),fb=find_f(b);            if (fa!=fb) {                tot--;add(g[fa],-1);add(g[fb],-1);                f[fa]=fb;g[fb]+=g[fa];add(g[fb],1);            }        } else {            scanf("%d", &k);            printf("%d\n", ask_k(tot-k+1));        }    }    return 0;}


0 0