poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
来源:互联网 发布:sim800a数据发送问题 编辑:程序博客网 时间:2024/05/16 19:20
题意:
有一群猫,现在给它们编号,然后组队,0 1 2 代表 1 号和 2 号的队伍合并。 1 4 询问第 4 大的队伍 Size 是多大。
解:(贴的,他写的好。表示学习)
线段树。建立一个线段树。每段记录group的大小在l与r之前的数目。初始时大小为1的组有N个,大小不为1的组均为0个。所以对于每段,若左边界为1,则其数据域为N,否则为0。以后不断合并group的过程中,设两个group的带大小分别为k1,k2。则线段树中包含k1或k2的结点数据域均减1,而包含k1+k2的结点数据域加1。因为合并后,原来大小为k1,k2的组已经不存在,取而代之的是新的大小为k1+k2的组。以后查询第k大的组则比较简单:在线段树上若未到达叶子结点,k若小于或等于右子树的数据域,则从右子树继续查询第k大的组;否则从左子树查询第k-s大的组,其中s为右子树的数据域,因为在右子树中已经有s个组比要查询的组大了,在左子树查询第k-s大的组即为所有组中第k大的组。
做题过程:
并查集那里和初始化那里出了一点问题。 并查集的话需要判断一下他们是不是在同一个集合,如果是在同一个集合,就不用合并了。
/*Pro: 0Sol:date:*/#include<cstdio>#include<cstring>const int maxn = 201001;#define lson l, m , rt << 1#define rson m + 1, r, rt << 1 | 1#define havem int m = (l + r) >> 1using namespace std;int sum[maxn << 2],p[maxn],num[maxn],n,Q;void build(int l, int r, int rt){ if(l == 1) sum[rt] = n; else sum[rt] = 0; //这里错了一次,初始化问题 if(l == r) return ; havem; build(lson); build(rson);}void update(int pos,int cc, int l, int r, int rt){//单点更新,凡是包含pos的节点都要改变 sum[rt] += cc; if(l == r) return ; havem; if(pos <= m) update(pos,cc,lson); else update(pos,cc,rson);}int query(int k, int l, int r, int rt){//单点询问 if(l == r) return l; havem; if(sum[rt << 1 | 1] >= k) return query(k,rson); else return query(k - sum[rt << 1 | 1],lson);}int find(int x){ return x==p[x] ? x : p[x]=find(p[x]);}int main(){ scanf("%d%d",&n,&Q); for(int i = 1; i <= n; i ++){ num[i] = 1; p[i] = i; } int op,a,b; build(1,n,1); for(int i = 1;i <= Q; i ++){ scanf("%d",&op); if(op == 0){ scanf("%d%d",&a,&b); int x = find(a); int y = find(b); if(x == y) continue ;//这里需要判断一下 update(num[x],-1,1,n,1); update(num[y],-1,1,n,1); update(num[x] + num[y],1,1,n,1); num[x] += num[y]; p[y] = x; }else{ scanf("%d",&a); printf("%d\n",query(a,1,n,1)); } } return 0;}
- poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
- poj 2985 The k-th Largest Group(线段树+并查集)
- POJ 2985 The k-th Largest Group 第k大数 Treap / 树状数组 + 并查集
- The k-th Largest (并查集+线段树)
- PKU2985(The k-th Largest Group)线段树+并查集
- POJ 题目2985 The k-th Largest Group(线段树单点更新求第k大值,并查集)
- POJ 2985The k-th Largest Group 线段树求整体第K大
- poj 2985 The k-th Largest Group 并查集+树状数组求第k大
- poj 2985(并查集+线段树求K大数)
- poj 2985 The k-th Largest Group/并查集+sbt
- poj 2985 The k-th Largest Group (Treap+并查集)
- Treap树(并查集 + 树堆)POJ —— 2985 The k-th Largest Group
- poj 2985 The k-th Largest Group (并查集x全局动态第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
- 关于gridview如何添加编辑删除
- POJ 2778 DNA Sequence(AC自动机+矩阵)
- SED单行脚本快速参考
- Google Map api key
- hdu 1220
- poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
- vc++学习笔记10
- GPU--图形处理器
- MyEclipse连接MySQL的方法
- Oracle中的pfile和spfile详解
- 开源Android pdf 解析
- mscrm 2011 高级查找中筛选查找条件中的多余实体记录
- 淘宝2013校园招聘提前电面经验分享
- Android adb shell 命令大全