题目描述

永无乡包含 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. win7右下角声音图标不见了

    场景:开机后发生右下角的声音图标不见了,马上google,可能性有两种图标隐藏或者系统错误 隐藏处理方式:右下角下打开自定义--> 将它调为显示和通知(发生不好使,估计是系统错误) 系统错误处理 ...

  2. C++11部分特性

    初识C++的时候,觉得会个STL就差不多了,后来发现了C++11这个东西,以及C++14,C++17QAQ,看了一下,好高深不学,emmmm真香= = 这里就只讲一下对ACM写代码有很高帮助的部分特性 ...

  3. CentOS在VMware中的安装

    1.启动VMware 2.新建一台虚拟机,选择典型 3.选择稍后安装操作系统 4.选择引导系统为Linux,系统版本为Centos 5.选择安装位置 6.选择最大磁盘容量 7.点击自定义硬件,进行硬件 ...

  4. 第四周课程总结&试验报告(二)

    实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握用类作为类型声明变量和方法返回值: 理解类和对象的区别,掌握构造函数的使用,熟悉通过对象名引用实例的方法和属性 ...

  5. charles 视图菜单总结

    本文参考:charles 视图菜单总结 Charles的视图菜单里的东西其实是非常常用的功能: 但是我们一般是不需要从这里点进来的: 里面,无非是查看的视图结构(按照域名和按照访问时间) 然后是一些概 ...

  6. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):如何安装 Nuget(dll) 后使用项目源代码调试

    最近碰到开发者问:我使用 nuget 安装了 Senparc.Weixin SDK,但是有一些已经封装好的过程想要调试,我又不想直接附加源代码项目,这样就没有办法同步更新了,我应该怎么办? 这其实是一 ...

  7. 30 道 Vue 面试题

    前言 本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性.框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度. 本文章节结构以从易到难进行组织,建议读者按章节顺 ...

  8. oracle 11g 下载安装 使用记录

    Oracle 11g 使用记录 1.下载oracle快捷安装版:   (1)下载连接:https://pan.baidu.com/s/1ClC0hQepmTw2lSJ2ODtL7g 无提取码 (2)去 ...

  9. .Net Core 添加 Swagger 支持

    1. NuGet  中添加 Swashbuckle.AspNetCore 2.添加 Startup 信息 将 Swagger 生成器添加到 Startup.ConfigureServices 方法中的 ...

  10. 【呕心总结】python如何与mysql实现交互及常用sql语句

    9 月初,我对 python 爬虫 燃起兴趣,但爬取到的数据多通道实时同步读写用文件并不方便,于是开始用起mysql.这篇笔记,我将整理近一个月的实战中最常用到的 mysql 语句,同时也将涉及到如何 ...