题目描述:

永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。

输入:

“输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000
对于 100%的数据 n≤100000,m≤n,q≤300000

输出:

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

题解:

并查集 + splay(其实所有的平衡树都可以) + 启发式合并

(题外话:这道题我真的是调得生无可恋啊,调了整整三天,提交了两页才调出来

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in","r",stdin);freopen(filename".out","w",stdout);
#endif #define R register
#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1<<15],*S=B,*T=B;
inline int FastIn()
{
R char ch;R int cnt=0;R bool minus=0;
while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ?minus=1:cnt=ch-'0';
while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus?-cnt:cnt;
}
#define maxn 100010
int val[maxn], Fa[maxn], ch[maxn][2], fa[maxn], size[maxn];
int Find(R int x){return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);}
inline void update(R int x)
{
R int ls = ch[x][0], rs = ch[x][1];
size[x] = size[ls] + size[rs] + 1;
}
inline void rotate(R int x)
{
R int f = fa[x], gf = fa[f], d = (ch[f][1] == x);
(ch[f][d] = ch[x][d ^ 1]) > 0 ? fa[ch[f][d]] = f : 0;
(fa[x] = gf) > 0 ? ch[gf][ch[gf][1] == f] = x : 0;
fa[ch[x][d ^ 1] = f] = x;
update(f);
}
inline void splay(R int x, R int rt)
{
while (fa[x] != rt)
{
R int f = fa[x], gf = fa[f];
if (gf != rt) rotate((ch[f][1] == x) ^ (ch[gf][1] == f) ? x : f);
rotate(x);
}
update(x);
}
void Insert(R int x, R int f)
{
if (val[x] < val[f])
{
if (ch[f][0])
Insert(x, ch[f][0]);
else
{
ch[f][0] = x; fa[x] = f;
}
}
else
{
if (ch[f][1])
Insert(x, ch[f][1]);
else
{
ch[f][1] = x; fa[x] = f;
}
}
update(f);
}
void merge(R int a, R int b)
{
R int tmp1 = 0, tmp2 = 0;
splay(a, 0);
splay(b, 0);
if (size[a] < size[b])
{
if (ch[a][0]) tmp1 = ch[a][0];
if (ch[a][1]) tmp2 = ch[a][1];
ch[a][0] = 0;
ch[a][1] = 0;
fa[tmp1] = 0;
fa[tmp2] = 0;
if (tmp1) merge(b, tmp1);
if (tmp2) merge(b, tmp2);
Insert(a, b);
}
else
{
if (ch[b][0]) tmp1 = ch[b][0];
if (ch[b][1]) tmp2 = ch[b][1];
ch[b][0] = 0;
ch[b][1] = 0;
fa[tmp1] = 0;
fa[tmp2] = 0;
if (tmp1) merge(a, tmp1);
if (tmp2) merge(a, tmp2);
Insert(b, a);
}
}
int find(R int x, R int k)
{
R int ls = ch[x][0], rs = ch[x][1], lsize = size[ls];
if (lsize + 1 == k) return x;
if (lsize >= k) return find(ls, k);
else return find(rs, k - lsize - 1);
}
int main()
{
R int n = FastIn(), m = FastIn();
for (R int i = 1; i <= n; ++i) val[i] = FastIn(), Fa[i] = i, size[i] = 1;
for (R int i = 1; i <= m; ++i)
{
R int a = FastIn(), b = FastIn();
Fa[Find(a)] = Find(b);
}
for (R int i = 1; i <= n; ++i){
R int f = Find(i);
if (f != i) Insert(i, f);
}
R int q = FastIn();
for (; q; --q)
{
R char opt = getc();
while (opt != 'Q' && opt != 'B') opt = getc();
R int a = FastIn(), b = FastIn();
if (opt == 'B')
{
R int f1 = Find(a), f2 = Find(b);
if (f1!=f2) merge(f1, f2), Fa[f1] = f2;
}
else
{
R int f = Find(a);
splay(f, 0);
if (size[f] < b) puts("-1");
else printf("%d\n",find(f,b) );
}
}
return 0;
}

【bzoj2733】[HNOI2012]永无乡的更多相关文章

  1. bzoj2733: [HNOI2012]永无乡 启发式合并

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec   ...

  2. bzoj2733: [HNOI2012]永无乡(splay)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3778  Solved: 2020 Description 永 ...

  3. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

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

  4. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  5. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  6. [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)

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

  7. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

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

  8. bzoj2733: [HNOI2012]永无乡 线段树合并

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

  9. BZOJ2733: [HNOI2012]永无乡(线段树合并)

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

  10. BZOJ2733 [HNOI2012]永无乡

    直接平衡树启发式合并就好了...貌似是个很高端的东西.. 貌似可以证明splay的启发式合并是均摊$O(nlogn)$的...而其他平衡树都不行,所以其他的复杂度都是$O(nlog^2n)的$的 所以 ...

随机推荐

  1. zimg 服务器配置文件

    --zimg server config --server config --是否后台运行 is_daemon = --绑定IP ip = '0.0.0.0' --端口 port = --运行线程数, ...

  2. Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.4 Predicates and Quantifiers

    The statements that describe valid input are known as preconditions and the conditions that the outp ...

  3. 【Linux开发】【Qt开发】嵌入式Qt程序使用触屏或USB鼠标方式

    上文<嵌入式Qt开发-移植到ARM开发板 >介绍了Qt程序的移植,本文再说下如何使开发板Qt程序使用触摸屏或USB方式进行交互. 之前刚把一个qt程序移植到arm板上成功运行显示时就开心的 ...

  4. 洛谷P1347 排序

    这个题看到很多人写Topo排序,其实这道题第一眼看更像是一个差分约束的裸题QWQ... 令dis[x]表示x的相对大小(1是最小,n是最大),显然,对于一个关系A<B,我们有dis[A]< ...

  5. python 开启进程两种方法 multiprocessing模块 介绍

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu\_count\(\)查看),在python中大部分情况需要使用多进 ...

  6. 红帽学习笔记[RHCSA] 第五课[用户、权限相关]

    第五课 用户权限 查看文件的权限 [kane@localhost /]$ ll total 36 ----------. 1 root root 1751 Aug 22 20:58 ~ lrwxrwx ...

  7. docker之配置TensorFlow的运行环境

    Docker是一种 操作系统层面的虚拟化技术,类似于传统的虚拟机.传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程:而容器内的应用进程直接运行于宿主的内核,容 ...

  8. [Python3] 042 日志

    目录 LOG 1. 日志相关概念 1.1 日志的级别 level 1.2 LOG 的作用 1.3 日志信息 1.4 成熟的第三方日志 1.5 注意 2. Logging 模块 2.1 日志级别 2.2 ...

  9. 单词数 HDU 2072 字符串输入控制

    单词数 HDU 2072 字符串输入控制 题意 lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数.下面你的任务是帮助xiaoou333解决这个 ...

  10. SCUT - 483 - 数轴上的点

    https://scut.online/p/483 改了题目之后发现,其实n个点放在[1,2N],要求间距至少是2,那么有且只有一个点和前面点的间距是3(设-1存在一个点),其他点的间距都必须是2.排 ...