题目描述

永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛。如果从岛 aaa 出发经过若干座(含 000 座)桥可以 到达岛 bbb ,则称岛 aaa 和岛 bbb 是连通的。

现在有两种操作:

B x y 表示在岛 xxx 与岛 yyy 之间修建一座新桥。

Q x k 表示询问当前与岛 xxx 连通的所有岛中第 kkk 重要的是哪座岛,即所有与岛 xxx 连通的岛中重要度排名第 kkk 小的岛是哪座,请你输出那个岛的编号。

输入输出格式

输入格式:

第一行是用空格隔开的两个正整数 nnn 和 mmm ,分别表示岛的个数以及一开始存在的桥数。

接下来的一行是用空格隔开的 nnn 个数,依次描述从岛 111 到岛 nnn 的重要度排名。随后的 mmm 行每行是用空格隔开的两个正整数 aia_iai​ 和 bib_ibi​ ,表示一开始就存在一座连接岛 aia_iai​ 和岛 bib_ibi​ 的桥。

后面剩下的部分描述操作,该部分的第一行是一个正整数 qqq ,表示一共有 qqq 个操作,接下来的 qqq 行依次描述每个操作,操作的 格式如上所述,以大写字母 QQQ 或 BBB 开始,后面跟两个不超过 nnn 的正整数,字母与数字以及两个数字之间用空格隔开。

输出格式:

对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表示所询问岛屿的编号。如果该岛屿不存在,则输出 −1-1−1 。

输入输出样例

输入样例#1:

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
输出样例#1:

-1
2
5
1
2

说明

对于 20% 的数据 n≤1000,q≤1000n \leq 1000, q \leq 1000n≤1000,q≤1000

对于 100% 的数据 n≤100000,m≤n,q≤300000n \leq 100000, m \leq n, q \leq 300000 n≤100000,m≤n,q≤300000

提交地址 : Luogu;

      bzoj

用并查集及维护, 无旋Treap直接启发式合并水过

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 100010 int n, m;
int rt[maxn], tot; struct fhq
{
int ch[];
int val;
int pri;
int siz;
}t[maxn]; int find(int x)
{
return x == rt[x] ? x : rt[x] = find(rt[x]);
} void pushup(int o)
{
t[o].siz = t[t[o].ch[]].siz + t[t[o].ch[]].siz + ;
} void Split(int o, int k, int &x, int &y)
{
if(!o) x = y = ;
else
{
if(t[o].val <= k)
{
x = o;
Split(t[o].ch[], k, t[o].ch[], y);
}
else
{
y = o;
Split(t[o].ch[], k, x, t[o].ch[]);
}
pushup(o);
}
} int Merge(int x, int y)
{
if(!x || !y) return x + y;
if(t[x].pri < t[y].pri)
{
t[x].ch[] = Merge(t[x].ch[], y);
pushup(x);
return x;
}
else
{
t[y].ch[] = Merge(x, t[y].ch[]);
pushup(y);
return y;
} } void insert(int &root, int y)
{
int a, b;
int v = t[y].val;
Split(root, v, a, b);
root =Merge(Merge(a, y), b);
} void DFS(int x, int &y)
{
if(!x) return;
DFS(t[x].ch[], y);
DFS(t[x].ch[], y);
t[x].ch[] = t[x].ch[] = ;
insert(y, x);
} int HeBing(int x, int y)
{
if(t[x].siz > t[y].siz) swap(x, y);
DFS(x, y);
return y;
} int K_th(int o, int k)
{
while()
{
if(k <= t[t[o].ch[]].siz)
{
o = t[o].ch[];
}
else if(k == t[t[o].ch[]].siz + )
{
return o;
}
else
{
k -= t[t[o].ch[]].siz + ;
o = t[o].ch[];
}
}
} int sz[maxn], old[maxn]; int main()
{
srand();
cin >> n >> m;
memset(old, -, sizeof old);
for(register int i = ; i <= n ; i ++)
{
scanf("%d", &t[i].val);
t[i].pri = rand();
t[i].siz = ;
rt[i] = i;
old[t[i].val] = i;
sz[i] = ;
} for(register int i = ; i <= m ; i ++)
{
int a, b, c;
scanf("%d%d", &a, &b);
int fx = find(a), fy = find(b);
if(fx == fy) continue; c = HeBing(rt[a], rt[b]); fx = find(a), fy = find(b); rt[fx] = rt[fy] = c; rt[c] = c;
} int q;
cin >> q;
while(q--)
{
char ch;
int x, y;
int a, b, c;
cin >> ch;
scanf("%d%d", &x, &y);
if(ch == 'Q')
{
int fx = find(x);
printf("%d\n", old[t[K_th(rt[x], y)].val]);
}
else
{
int fx = find(x), fy = find(y);
if(fx == fy) continue;
c = HeBing(rt[x], rt[y]);
fx = find(x), fy = find(y); rt[fx] = rt[fy] = c;
rt[c] = c; }
}
return ; }

zZhBr

HNOI2012 永无乡 无旋Treap的更多相关文章

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

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

  2. 【bzoj2733】永无乡(无旋treap启发式合并 + 并查集)

    传送门 题目分析 起初每个岛都是一个平衡树, 并查集的祖先都是自己.合并两岛时,pri较小的祖先会被作为合并后的祖先, 而两颗平衡树采用启发式合并.查询k值就是基本操作. code #include& ...

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

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

  4. 【bzoj2733】[HNOI2012]永无乡 Treap启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

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

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

  6. [Luogu 3224] HNOI2012 永无乡

    [Luogu 3224] HNOI2012 永无乡 特别水一个平衡树题. 不认真的代价是调试时间指数增长. 我写的 SBT,因为 Treap 的 rand() 实在写够了. 用并查集维护这些点的关系, ...

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

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

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

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

  9. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

随机推荐

  1. 大数据平台搭建 - cdh5.11.1 - hbase集群搭建

    一.简介 HBase是一种构建在HDFS之上的分布式.面向列的存储系统.在需要实时读写.随机访问超大规模数据集时,可以使用HBase. 尽管已经有许多数据存储和访问的策略和实现方法,但事实上大多数解决 ...

  2. Java秒杀系统优化的工程要点

    这篇博客是笔者学习慕课网若鱼老师的<Java秒杀系统方案优化 高性能高并发实战>课程的学习笔记.若鱼老师授课循循善诱,讲解由浅入深,欢迎大家支持. 本文记录课程中的注意点,方便以后code ...

  3. jenkins离线安装插件的方法(无法访问外网)

    最近项目要迁移环境,无法访问外网,因此jenkins的安装配置需要离线操作,在此记录 jenkins下载安装好之后,跳过插件的安装,新建用户进入jenkins界面,这些前置步骤我在之前的随笔里有写具体 ...

  4. 欢迎加入强哥的 Android 开发交流群

    最近建了一个 Android 开发交流群,但不限于交流移动端.前端和后端等相关技术. 本群的宗旨:让所有学习的群友都有进步的机会. 1. 经验交流 在我们学习时遇到困境,或者开发过程中遇到难题,都可以 ...

  5. alpha测试和beta测试的区别

    alpha测试版,有点相当于内部测试,一般开发人员在场   ,是由用户做测试,但开发人员在场,一般是请用户到开发现场去测试  beta测试版,完全交给用户,由用户做测试,返回测试报告,相当于发行前的一 ...

  6. (6)autotools工具的使用

       autotools是专门用来生成Makefile的一系列工具,包括autoscan.aclocal.autoheader.autoconf.automake等.     (1)autotools ...

  7. layui-table与layui-rate评分转换成星级的使用

    需求:将layui-table中的某一列,例如:评分,从数据库中查找出来之后,进行layui-rate评分转换显示效果,为星星.显示效果如下: 实现代码: 1.layui中引入rate 2.table ...

  8. 夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  9. 关于CSS的书写规范和顺序

    关于CSS的书写规范和顺序,是大部分前端er都必须要攻克的一门关卡,如果没有按照良好的CSS书写规范来写CSS代码,会影响代码的阅读体验.这里总结了一个CSS书写规范.CSS书写顺序供大家参考,这些是 ...

  10. url设计规范

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...