poj2985线段树求第k大的数(并查集)

来源:互联网 发布:权力的游戏大麻雀知乎 编辑:程序博客网 时间:2024/05/29 03:22
The k-th Largest Group
Time Limit: 2000MS Memory Limit: 131072KTotal Submissions: 7255 Accepted: 2335

Description

Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is really huge, Newman wants to group some of the cats. To do that, he first offers a number to each of the cat (1, 2, 3, …,n). Then he occasionally combines the group cat i is in and the group cat j is in, thus creating a new group. On top of that, Newman wants to know the size of the k-th biggest group at any time. So, being a friend of Newman, can you help him?

Input

1st line: Two numbers N and M (1 ≤ NM ≤ 200,000), namely the number of cats and the number of operations.

2nd to (m + 1)-th line: In each line, there is number C specifying the kind of operation Newman wants to do. If C = 0, then there are two numbers i and j (1 ≤ ij ≤ n) following indicating Newman wants to combine the group containing the two cats (in case these two cats are in the same group, just do nothing); If C = 1, then there is only one number k (1 ≤ k ≤ the current number of groups) following indicating Newman wants to know the size of the k-th largest group.

Output

For every operation “1” in the input, output one number per line, specifying the size of the kth largest group.

Sample Input

10 100 1 21 40 3 41 20 5 61 10 7 81 10 9 101 1

Sample Output

12222

Hint

When there are three numbers 2 and 2 and 1, the 2nd largest number is 2 and the 3rd largest number is 1.

Source

POJ Monthly--2006.08.27, zcgzcgzcg
//线段树每个节点维护的是group大小在这个区间的个数//每次更新时,包含a[x]和a[y] group大小的区间分别减1//而包含a[x]+a[y]的区间加1,询问的时候,先询问右子树//如果右子树的cnt>=k,则去右子树继续查询,否则去左子树//并且k-=rson的cnt。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define maxn 200005#define ls(o) o<<1#define rs(o) (o<<1)|1#define Mid(a,b) (a + b)>>1#define Fill(s,e,xx) for(int i=s;i<e;i++)a[i]=xx;int fa[maxn],Rank[maxn],n,m;void init(int n)//一定要记得初始化{    for(int i=0;i<=n;i++)fa[i]=i,Rank[i]=0;}int find_fa(int x)//查询是否已经在同一组了{    if(fa[x]!=x)fa[x]=find_fa(fa[x]);    return fa[x];}void Union(int x,int y)//在这里并不需要这么合并,^-^,算是无用吧{    x = find_fa(x);    y = find_fa(x);    if(x==y)return;    if(Rank[x]<Rank[y]){        fa[x] = y;    }    else{        fa[y] = x;        if(Rank[x]==Rank[y])Rank[x]++;    }}struct line_tree{    int l,r;//存储区间信息    int cnt;//存储在该区间内,有多少区间在该区间内的group}tree[maxn<<2];void build(int tl,int tr,int o){    tree[o].l=tl,tree[o].r=tr;    if(tl==1)tree[o].cnt = n;    else tree[o].cnt = 0;    if(tl == tr){        return;    }    int mid = Mid(tl,tr);    build(tl,mid,ls(o));    build(mid+1,tr,rs(o));}void Insert(int x,int o,int c){    tree[o].cnt+=c;    if(tree[o].l == tree[o].r)return;    if(x<=tree[ls(o)].r)Insert(x,ls(o),c);    else Insert(x,rs(o),c);}int query(int k,int o=1){    if(tree[o].l==tree[o].r){        printf("%d\n",tree[o].l);        return 0;    }    if(k<=tree[rs(o)].cnt)query(k,rs(o));//右子树有大于k个数,第k个数肯定在右边。。。。//求的是第k大数。。。。所以从右子树查询    else query(k-tree[rs(o)].cnt,ls(o));}int a[maxn];//存储group信息int  main(){    while(scanf("%d%d",&n,&m)==2){        Fill(0,n+1,1);        build(1,n,1);init(n);        for(int i=0;i<m;i++){            int com;            scanf("%d",&com);            if(com==0){                int x,y;                scanf("%d%d",&x,&y);                x = find_fa(x),y=find_fa(y);                if(x==y)continue;                Insert(a[x],1,-1);                Insert(a[y],1,-1);                Insert(a[x]+a[y],1,1);                fa[y] = x;//两个一定要一致。。。。。。。。。。                a[x]+=a[y];            }            else{                int k;                scanf("%d",&k);                query(k);            }        }    }    return 0;}

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 刚出生的小羊不吃奶怎么办 羔羊走路不稳不吃奶怎么办 新生儿喝奶老是呛到怎么办 宝宝吃母乳呛到怎么办 宝宝一直睡觉不吃奶怎么办 3个月婴儿不吃奶怎么办 新生婴儿晚上不睡觉怎么办 宝宝肚子胀不吃奶怎么办 宝宝25天不睡觉怎么办 50天婴儿不吃奶怎么办 儿子关在房间玩电脑怎么办? 宽带拨号上网账号密码忘了怎么办 双眼皮割的太宽怎么办 营业执照异常名录移除注销怎么办 工商局注册后骚扰电话怎么办 单位工作失误医保断交7年怎么办 大门对大门怎么办?巧用天官赐福 委托书公司名称打错了怎么办 招行ubank不对账怎么办 信贷公司利息高不合理怎么办 衣服上的logo掉怎么办 ui设计师接不到私活怎么办 微信打开很慢怎么办 小泰迪感冒加身上结痂怎么办 法斗眼睛肿了怎么办 地图鱼身上有白点怎么办 人被广告牌砸了怎么办 小米手机出现繁体中文英文怎么办 雅思考试把姓名写错了怎么办 房贷的流水账假怎么办 报到证报道期限过期了怎么办 注销公司公章丢了怎么办 家里的猫太调皮怎么办 孩子纹身了我该怎么办 46天婴儿感冒了怎么办 狗病了不吃东西怎么办 幼儿急诊见风了怎么办 哺乳期乳房有硬块而且疼怎么办 哺乳期乳头破裂乳房似针扎怎么办 回奶胀痛的厉害怎么办 淡水龟的壳变软了怎么办