题意:

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]永无乡 (权值线段树启发式合并+并查集)的更多相关文章

  1. BZOJ2733/LG3324 「HNOI2014」永无乡 权值线段树合并

    问题描述 BZOJ2733 LG3224 题解 对于每个结点建立一棵权值线段树. 查询操作就去查询第 \(k\) 大,合并操作就合并两颗权值线段树. 并查集维护连通性. 同时 STO hkk,zcr, ...

  2. bzoj 2733: [HNOI2012]永无乡 -- 线段树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...

  3. Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...

  4. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  5. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  6. bzoj 2733: [HNOI2012]永无乡 离线+主席树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1167  Solved: 607[Submit][Status ...

  7. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

  8. Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3955  Solved: 2112[Submit][Statu ...

  9. bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】

    bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...

随机推荐

  1. spring boot中使用freemarker

    在做Java web开发领域,web模板引擎主要有jsp.freemarker.velocity,其中freemarker是我们常用的一种,在spring boot中使用的freemarker的方法可 ...

  2. 【JDBC】Java程序的数据库初体验

    JDBC是什么 JDBC是一种能够用来执行SQL语句的Java API[接口]. 它是Java提供的一种规范,让各大数据库厂商遵循此规范完成自己的数据库连接驱动[实现接口]. JDBC的入门程序(这里 ...

  3. 【转】常见Java面试题 – 第二部分:equals与==

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q2.下面的代码片段的输出是什么? Object s1 = new St ...

  4. 越来越清晰的TFRecord处理图片的步骤

    # 首先是模块的导入 """ os模块是处理文件夹用的 PIL模块是用来处理图片的 """ import tensorflow as tf ...

  5. JS的var和let的区别(详细讲解)

    let是ES6新增的,它主要是弥补var的缺陷,你也可以把let看做var的升级版.下面我就来详细讲讲var和let的区别 相同点: var和let都有函数级作用域 不同点: (1)var是全局作用域 ...

  6. c++ 快读快输模板

    快读 inline int read() { ; ; char ch=getchar(); ; ch=getchar();} )+(X<<)+ch-'; ch=getchar();} if ...

  7. 通过VS2019使用Web部署发布.net core程序

    服务器:Windows Server2012R2 服务器已安装好IIS 需要启用Web Management Service  与 Web部署代理服务 服务器默认是没有Web部署代理服务的  需要安装 ...

  8. MySql笔记(一)

    目录 MySql笔记(一) 每天给自己一个希望,努力做好自己,不为明天烦恼,不为昨天叹息.当梦想还在,告诉自己:努力,就总能遇见更好的自己! MySql笔记(一) 1.创建数据库以及删除 1.创建数据 ...

  9. Activiti结束事件(End Event)

    Activiti结束事件(End Event) 作者:Jesai -2017.08.03T01:03 曾经,黑夜多么漫长,八月雨扰眠,缘何? 声明:版权所有,如需引用请注明出处,如发现抄袭,必追究法律 ...

  10. python StringIO和ByteIO

    一.StringIO 1.作用:在内存在读写str # 导入模块 from io import StringIO # 实例化StringIO对象 str_io = StringIO() # 向内存中写 ...