poj 2985 The k-th Largest Group(线段树+并查集)
来源:互联网 发布:c语言中的运算符 编辑:程序博客网 时间:2024/05/17 06:00
题目链接http://poj.org/problem?id=2985
题意:
有N只猫,刚开始每只猫各自在不同的集合,现在给出M个操作,有两种操作:
1.把第i只猫和第j只猫所在集合合并。
2.查找第i大的集合内有多少只猫。
思路:
操作一,集合合并很容易想到并查集。
操作二,如果每次合并之后进行查找直接遍历一遍,效率O(n^2),很容易超时。所以可以考虑用线段树或者树状数组优化。(毕竟数据结构主要就是查找删除等操作优化)
此题是线段树的单点更新单点查询问题。
sum[i]表示集合内的个数在区间[L,R]的集合的个数;(炒鸡绕口...)
每次更新时,从上而下将集合内的个数在[L,R]的所有区间进行更新(也算是一个小的优化吧)
查询时,只需要判断k<=sum[rt<<1|1],往右;否则往左(找的是第k大,如果是第k小,则比较k和sum[rt<<1])
#include <iostream>#include <cstdio>#include <cmath>using namespace std;#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rtypedef long long ll;const int INF=0x3f3f3f3f;const int maxn=2e5+10;int T,n,m;int f[maxn],r[maxn];int sum[maxn<<2];void Make_Set(){for(int i=1;i<=n;i++) f[i]=i,r[i]=1;}int find(int x){return x==f[x]?x:f[x]=find(f[x]);}void build(int rt,int l,int r){sum[rt]=(l==1?n:0);if(l==r) return ;int mid=(l+r)>>1;build(lson);build(rson);}void Update(int rt,int l,int r,int val,bool flag){sum[rt]+=(flag?1:-1);if(l==r) return ;int mid=(l+r)>>1;if(val<=mid) Update(lson,val,flag);else Update(rson,val,flag);}int Query(int rt,int l,int r,int k){if(l==r) return l;int mid=(l+r)>>1;if(k<=sum[rt<<1|1]) return Query(rson,k);else return Query(lson,k-sum[rt<<1|1]);}int main(){#ifndef ONLINE_JUDGEfreopen("test.in","r",stdin);freopen("test.out","w",stdout);#endifwhile(~scanf("%d%d",&n,&m)){Make_Set();build(1,1,n);int op,a,b,k;for(int i=1;i<=m;i++){scanf("%d",&op);if(!op){scanf("%d%d",&a,&b);int ra=find(a);int rb=find(b);if(ra==rb) continue;Update(1,1,n,r[ra],false);Update(1,1,n,r[rb],false);Update(1,1,n,r[ra]+r[rb],true);f[rb]=ra;r[ra]+=r[rb];}else{scanf("%d",&k);printf("%d\n",Query(1,1,n,k));}}}return 0;}
0 0
- poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
- poj 2985 The k-th Largest Group(线段树+并查集)
- POJ 题目2985 The k-th Largest Group(线段树单点更新求第k大值,并查集)
- poj 2985 The k-th Largest Group 并查集+树状数组求第k大
- POJ 2985 The k-th Largest Group 第k大数 Treap / 树状数组 + 并查集
- PKU2985(The k-th Largest Group)线段树+并查集
- poj 2985 The k-th Largest Group/并查集+sbt
- poj 2985 The k-th Largest Group (Treap+并查集)
- The k-th Largest (并查集+线段树)
- Treap树(并查集 + 树堆)POJ —— 2985 The k-th Largest Group
- POJ2985 The k-th Largest Group(treap+并查集)
- poj 2985 The k-th Largest Group (并查集x全局动态第k大)
- POJ 2985The k-th Largest Group 线段树求整体第K大
- 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]
- java_annotation
- HDU 4990 Reading comprehension
- caffe blob and cv::Mat
- 一个Python使用实例
- java学习之路之java基本语法之变量
- poj 2985 The k-th Largest Group(线段树+并查集)
- 美素数
- HDU:1997 汉诺塔VII(规律||递归)
- 文章标题
- nginx的安装
- Eclipse报错:java.lang.ClassNotFoundException: ContextLoaderListener
- 【一天一道LeetCode】#225. Implement Stack using Queues
- UVA-562 Dividing coins(01背包)
- Cow Exhibition(多重背包问题)