[HNOI2012] 永无乡 解题报告 (splay+启发式合并)
题目链接:https://www.luogu.org/problemnew/show/P3224#sub
题目:
题目大意:
维护多个联通块,没有删除操作,每次询问某一联通块的第k大
解法:
维护联通块我们用并查集,询问第k大用splay,合并的时候splay暴力启发式合并就是了
启发式合并:把size小的splay合并到size大的splay上,暴力插入就好了
这道题的具体做法就是我们记录rt数组表示每个点的splay的根,在每次连边的时候就是把一方的根的所有节点全部插入到另一方的根去
其他的可以参考我在洛谷的博客里写的东西:https://www.luogu.org/blog/xxzh2425/solution-p3224
AC代码如下:
// luogu-judger-enable-o2
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cctype>
#include<cstdlib>
#define ri register int
using namespace std; const int N=1e5+;
int n,m;
int f[N],rt[N],w[N],fa[N];
std::queue <int> dl;
struct Splay
{
int ch[];
int ff,size;
}t[N];
inline int read()
{
char ch=getchar();
int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
inline int find(int x)
{
if (fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
inline void pushup(int x)
{
t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+;
}
inline void rotate(int x)
{
int y=t[x].ff;
int z=t[y].ff;
int k=t[y].ch[]==x;
t[z].ch[t[z].ch[]==y]=x;
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^];
t[t[x].ch[k^]].ff=y;
t[x].ch[k^]=y;
t[y].ff=x;
pushup(y);pushup(x);
}
inline void splay(int x,int goal)
{
while (t[x].ff!=goal)
{
int y=t[x].ff,z=t[y].ff;
if (z!=goal) (t[y].ch[]==x)^(t[z].ch[]==y)?rotate(x):rotate(y);
rotate(x);
}
}
inline void insert(int x,int &now,int fat)
{
if (!now)
{
now=x;
t[x].ff=fat;
return;
}
t[now].ff=fat;
t[now].size++;
if (w[x]<=w[now]) insert(x,t[now].ch[],now);
else insert(x,t[now].ch[],now);
}
inline void mergy(int x,int y)
{
if (x==y) return;
if (t[rt[x]].size>t[rt[y]].size) std::swap(x,y);
fa[rt[x]]=rt[y];
dl.push(rt[x]);
while (!dl.empty())
{
int k=dl.front();
dl.pop();
if (t[k].ch[]) dl.push(t[k].ch[]);
if (t[k].ch[]) dl.push(t[k].ch[]);
insert(k,rt[y],);
rt[k]=rt[y];
//splay(k,rt[y]);
}
}
inline int kth(int x,int k)
{
int now=rt[x];
if (t[now].size<k) return -;
while ()
{
if (t[t[now].ch[]].size>=k) now=t[now].ch[];
else if (t[t[now].ch[]].size+==k) return now;
else k-=t[t[now].ch[]].size+,now=t[now].ch[];
}
}
inline void write(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int main()
{
n=read();m=read();
for (ri i=;i<=n;i++)
{
w[i]=read();
rt[i]=i;fa[i]=i;t[i].size=;
}
for (ri i=;i<=m;i++)
{
int u=read(),v=read();
mergy(u,v);
}
int q=read();
while (q--)
{
char ch=getchar();
while (!(ch=='Q'||ch=='B')) ch=getchar();
int x=read(),y=read();
if (ch=='Q')
{
int ans=kth(find(x),y);
write(ans);putchar('\n');
}
else
{
mergy(find(x),find(y));
}
}
return ;
}
诚恳地建议:
去看看我在洛谷博客里写的东西
[HNOI2012] 永无乡 解题报告 (splay+启发式合并)的更多相关文章
- 洛谷 P3224 [HNOI2012]永无乡 解题报告
P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...
- [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并
好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...
- 2733. [HNOI2012]永无乡【平衡树-splay】
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- [HNOI2012]永无乡 线段树合并
[HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3955 Solved: 2112[Submit][Statu ...
- bzoj2733: [HNOI2012]永无乡 启发式合并
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec ...
- bzoj2733: [HNOI2012]永无乡(splay)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3778 Solved: 2020 Description 永 ...
- Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...
随机推荐
- 怎样制作C#安装程序
近期须要制作一个C#安装.在网上找了一些资料发现都不是非常完整,最后自己综合了一些资料,而且通过亲自检測,最后成功完毕C#打包成安装程序(打包成最简单的一种安装程序.假设须要更高的功能请自己在开发). ...
- Cocos2d-x 3.0多线程异步资源载入
Cocos2d-x从2.x版本号到上周刚刚才公布的Cocos2d-x 3.0 Final版,其引擎驱动核心依然是一个单线程的"死循环".一旦某一帧遇到了"大活儿" ...
- UVA 1329 Corporative Network【并查集】
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- oracle 下操作blob字段是否会产生大量redo
操作blob字段是否会产生大量redo,答案是不会.以下来做一个实验,測试数据库版本号是11.2.0.1.0: --创建一张表做測试之用 create table test_blob ( id n ...
- fieldset 标签 -- 对表单进行分组
转自:https://xhmaomy-163-com.iteye.com/blog/1066977 fieldset——一个不常用的HTML标签 fieldset 标签 -- 对表单进行分组 在for ...
- MongoDB 系列(一) C# 类似EF语法简单封装
之前写过一篇关于MongoDB的封装 发现太过繁琐 于是打算从新写一篇简易版 1:关于MongoDB的安装请自行百度,进行权限认证的时候有一个小坑,3.0之后授权认证方式默认的SCRAM-SHA-1模 ...
- 升级Ubuntu18.04后遇到的坑
升级过程: 直接do-release-update 就可以直接从16.04更新到18.04了. 中间会提升更新一些配置文件, 我大部分都选择了N. 然后就成功升级到18.04了, 显卡驱动什么的都 ...
- SSRS故障排除
1.SSRS部署到本地出现错误:为用户“Jimmy-PC\Jimmy”授予的权限不足,无法执行此操作.用户“Jimmy-PC\Jimmy”不具有所需的权限.请验证授予了足够的权限并且解决了 Windo ...
- PostgreSQL 数据库性能调优的注意点
PostgreSQL提供了一些性能调优的功能.主要有如下几个方面.1.使用EXPLAIN EXPLAIN命令可以查看执行计划,这个方法是我们最主要的调试工具. 2.及时更新执行计划中使用的统计信息 ...
- python中index、slice与slice assignment用法
python中index.slice与slice assignment用法 一.index与slice的定义: index用于枚举list中的元素(Indexes enumerate the elem ...