BZOJ 2733 [HNOI2012]永无乡 (权值线段树启发式合并+并查集)
题意:
n<=1e5的图里,在线连边、查询某连通块第k大
思路:
练习线段树合并的好题,因为依然记得上一次启发式合并trie的时候内存爆炸的恐怖,所以这次还是用了动态开点、回收
听说启发式合并splay更快QAQ,学会了试试
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e5+;
const int maxm = 6e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n,m;
int q;
int ls[maxn*],rs[maxn*],dat[maxn*];
int root[maxn];
int a[maxn],id[maxn]; int f[maxn];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
} int tot;
queue<int>pool;
int New(){
if(!pool.empty()){
int x = pool.front();
pool.pop();
return x;
}
++tot;
return tot;
}
void del(int x){
if(!x)return;
pool.push(x);
return;
}
int build(int l, int r, int x){
int mid = (l+r)>>;
int p = New();
dat[p]=;
if(l==r)return p;
if(x<=mid)ls[p]=build(l,mid,x);
else rs[p]=build(mid+,r,x);
return p;
}
int merge(int p, int q){// leave p
if(!p)return q;
if(!q)return p;
ls[p]=merge(ls[p],ls[q]);
rs[p]=merge(rs[p],rs[q]);
dat[p]+=dat[q];
ls[q]=rs[q]=dat[q]=;
del(q);
return p;
}
int query(int x, int l, int r, int k){
int mid = (l+r)>>;
if(l==r)return l;
if(dat[ls[x]]>=k){
return query(ls[x],l,mid,k);
}
else{
return query(rs[x],mid+,r,k-dat[ls[x]]);
}
}
int main() {
scanf("%d %d" ,&n, &m);
for(int i = ; i <= n; i++){
f[i]=i;
scanf("%d", &a[i]);
id[a[i]]=i;
root[i]=build(,n,a[i]);
}
/*for(int i = 1; i <= n; i++){
printf("-- %d root::%d\n",i,root[i]);
}
for(int i = 1; i <= tot; i++){
//printf("%d ==== %d %d %d\n",i,ls[i],rs[i],dat[i]);
}*/
for(int i = ; i <= m; i++){
int x,y;
scanf("%d %d" ,&x, &y);
int t1 = find(x);
int t2 = find(y);
if(t1!=t2){
root[t1]=merge(root[t1],root[t2]);
f[t2]=t1;
}
}
scanf("%d", &q);
while(q--){
char op[];
int x,y;
scanf("%s %d %d", op,&x,&y);
if(op[]=='Q'){
int t = find(x);
if(dat[root[t]]<y){printf("-1\n");continue;}
else printf("%d\n",id[query(root[t],,n,y)]);
}
else{
int t1 = find(x);
int t2 = find(y);
if(t1!=t2){
root[t1]=merge(root[t1],root[t2]);
f[t2]=t1;
}
}
}
return ;
}
/*
5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3
*/
BZOJ 2733 [HNOI2012]永无乡 (权值线段树启发式合并+并查集)的更多相关文章
- BZOJ2733/LG3324 「HNOI2014」永无乡 权值线段树合并
问题描述 BZOJ2733 LG3224 题解 对于每个结点建立一棵权值线段树. 查询操作就去查询第 \(k\) 大,合并操作就合并两颗权值线段树. 并查集维护连通性. 同时 STO hkk,zcr, ...
- bzoj 2733: [HNOI2012]永无乡 -- 线段树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...
- Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1167 Solved: 607[Submit][Status ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3955 Solved: 2112[Submit][Statu ...
- bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】
bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...
随机推荐
- java数据结构之常用排序算法
冒泡排序 private void maopao(int arr[]) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j &l ...
- Intellij Idea插件使用记录之Alibaba Java Coding Guidelines
目录 Intellij Idea插件Alibaba Java Coding Guidelines 前言 使用 感谢 Intellij Idea插件Alibaba Java Coding Guideli ...
- 在Windows Server 2003中搭建DNS服务器
1.安装Windows Server 2003虚拟机 准备好Windows Server 2003的镜像:http://www.downza.cn/soft/184944.html 2.Windows ...
- Spring工程报错
错误日志: 2014-09-24 10:50:16 [org.springframework.context.support.FileSystemXmlApplicationContext]-[INF ...
- 大白话建造者模式(Builder Pattern)
前言 起初打算按照之前的日产系列写建造者模式.但参考了网上的很多文章,让我对建造者模式更加的困惑,也害怕自己无法已易懂的方式进行解释.最后通过Google发现了一篇英文文章Builder,使我茅塞顿开 ...
- Java小白集合源码的学习系列:Vector
目录 Vector源码学习 Vector继承体系 Vector核心源码 基本属性 构造器 扩容机制 Enumeration 概述 源码描述 具体操作 Vector总结 Vector源码学习 前文传送门 ...
- 树形dp - 求树的直径
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...
- 安装dbeaver,The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
在连接mysql时,出现了以下错误: 解决方法是 在数据库链接指定useUnicode=true&useSSL=false&characterEncoding=utf8&ser ...
- 世界上最流行的版本控制系统——Git
版本控制系统,也就是VCS(Version Control System),可以说是程序员必备的工具.那么它到底是什么,有什么作用呢? 举个例子,如果你想查看你所开发的软件在一个月之前的模样,同时还想 ...
- 如何选择kmeans中的k值——肘部法则–Elbow Method和轮廓系数–Silhouette Coefficient
肘部法则–Elbow Method 我们知道k-means是以最小化样本与质点平方误差作为目标函数,将每个簇的质点与簇内样本点的平方距离误差和称为畸变程度(distortions),那么,对于一个簇, ...