bzoj2733: [HNOI2012]永无乡(splay)
2733: [HNOI2012]永无乡
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3778 Solved: 2020
Description
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。
Input
输入文件第一行是用空格隔开的两个正整数 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
Output
对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。
Sample Input
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
Sample Output
2
5
1
2
分析
可以用并查集维护连通性,这个没啥好说的。
然后 Splay 启发式合并,合并时,直接将小的暴力加入另一个。
这个调试了好久qwq。洛谷上还t了最后一个点
code
#include<cstdio>
#include<algorithm> using namespace std; const int MAXN = ;
int fa[MAXN],pa[MAXN],val[MAXN],ch[MAXN][],siz[MAXN],q[MAXN];
int n,m;
char opt[]; int read()
{
int x = , f = ;char ch = getchar();
while (ch<''||ch>'') {if(ch=='-')f=-; ch=getchar(); }
while (ch>=''&&ch<='') {x=x*+ch-''; ch=getchar(); }
return x*f;
}
void pushup(int x)
{
if (!x) return ;
siz[x] = siz[ch[x][]]+siz[ch[x][]]+;
}
int son(int x)
{
return ch[fa[x]][]==x;//不是等于1,qwq
}
void rotate(int x)
{
int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
if (z) ch[z][c] = x;fa[x] = z;
if (a) fa[a] = y;ch[y][b] = a;
ch[x][!b] = y;fa[y] = x;
pushup(y); }
void splay(int x,int rt)
{
while (fa[x]!=rt)
{
int y = fa[x],z = fa[y];
if (z==rt) rotate(x);
else
{
if (son(x)==son(y)) rotate(y),rotate(x);
else rotate(x), rotate(x);
}
}
pushup(x);
}
void insert(int &x,int pre,int id)
{
if (!x)
{
x = id;fa[x] = pre;siz[x] = ;
splay(x,);
return ;
}
if (val[id]<=val[x]) insert(ch[x][],x,id);
else insert(ch[x][],x,id);
pushup(x);
}
int getkth(int x,int k)
{
if (k< || k>siz[x]) return -;
while (k<=siz[ch[x][]] || k>siz[ch[x][]]+)//x是变的,不能直接l = ch[x][0],用l代替chp[x][0]使用
if (k<=siz[ch[x][]]) x = ch[x][];
else k -= siz[ch[x][]]+, x = ch[x][];;
splay(x,);
return x;
}
void merge(int x,int y)
{
splay(x,);splay(y,);
if (siz[x]>siz[y]) swap(x,y);//启发式合并
int head = , tail = ;
q[] = y,q[] = x;
while (head<tail)
{
int t = q[++head];
if (ch[t][]) q[++tail] = ch[t][];
if (ch[t][]) q[++tail] = ch[t][];
ch[t][] = ch[t][] = ;
insert(q[head-],,t);
}
}
int find(int x)
{
return pa[x]==x?x:pa[x]=find(pa[x]);
}
int main()
{
n = read(),m = read();
for (int i=; i<=n; ++i)
{
val[i] = read();
pa[i] = i;siz[i] = ;
}
for (int x,y,i=; i<=m; ++i)
{
x = read();y = read();
if (find(x)!=find(y))
{
merge(x,y);
pa[find(x)] = find(y);//设为find(y),不是y
}
}
int t = read();
while (t--)
{
scanf("%s",opt);
int x = read(), y = read();
if (opt[]=='Q')
{
splay(x,);
printf("%d\n",getkth(x,y));
}
else
{
if (find(x)!=find(y))
{
merge(x,y);
pa[find(x)] = find(y);
}
}
}
return ;
}
bzoj2733: [HNOI2012]永无乡(splay)的更多相关文章
- [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- 【BZOJ-2733】永无乡 Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2048 Solved: 1078[Submit][Statu ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- bzoj2733: [HNOI2012]永无乡 启发式合并
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec ...
- [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4108 Solved: 2195[Submit][Statu ...
- [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并
永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...
- BZOJ2733 [HNOI2012]永无乡 【线段树合并】
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- bzoj2733: [HNOI2012]永无乡 线段树合并
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...
随机推荐
- .Net Core+mySqlSugar的一些稍复杂操作
介绍一些我尝试的mysqlSugar的数据库操作 修改密码 var status = db.Update<Users>(new { password = user.password }, ...
- BZOJ3693: 圆桌会议(Hall定理 线段树)
题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...
- WPF中的拖放1
实现了WPF的不同层级间的元素之间的拖放,例子虽小却很经典,引申一下也许可以实现类VS界面的浮动依靠面板. 拖放前: 拖放后: 代码如下: <Window x:Class="WpfAp ...
- Spring MVC + Thymeleaf
参考网址: https://www.cnblogs.com/litblank/p/7988689.html 一.简介 1.Thymeleaf 在有网络和无网络的环境下皆可运行,而且完全不需启动WEB应 ...
- java 创建一个新的http 请求的一种实现方式
项目中遇到要在后台向集群中的其他一台服务器发送一个请求,参考了网上一些材料,最终完成了需求.代码如下 /** * @Title requestURLWithPost * @Description:发送 ...
- 约瑟夫环问题及PHP代码实现
php实现猴子选大王 <?php /** * @param $n 猴子数量 * @param $m 出列的那个数 */ function king($n,$m){ $monkeys = rang ...
- 自动化构建工具gulp的基础了解
1.使用gulp的步骤 1.安装node检测是否安装好 cmd->node -v2.安装gulp 可以在npm或者在cnpm3.在node里面有个文件package.json.利用命令行npm ...
- hdu-1162 Eddy's picture---浮点数的MST
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1162 题目大意: 给n个点,求MST权值 解题思路: 直接prim算法 #include<bi ...
- fopen, fdopen, freopen - 打开流
SYNOPSIS (总览) #include <stdio.h> FILE *fopen(const char *path, const char *mode); FILE *fdopen ...
- Java后台工程师的3次面试
第一次面试 我面的是一个中小公司,在BOSS直聘上面找的,去之前看了看关于Java的一些基础知识,在牛客网上面看的,也做了一下牛客网的题目.然后跟HR约了一个时间就去面试了.因为第一次面试,一点经验都 ...