[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,每座岛都有自己 ...
随机推荐
- [CSS3] CSS Background Images
Body with background image and gradient html { background: linear-gradient(#000, white) no-repeat; h ...
- glove入门实战
前两天怒刷微博,突然发现了刘知远老师分享的微博,顿时眼前一惊.原Po例如以下: http://weibo.com/1464484735/BhbLD70wa 因为我眼下的研究方向是word2vec.暗自 ...
- 安卓WebView的使用,在应用程序中嵌入一个浏览器,轻松地展示各种各样的网页
WebView 在应用程序中嵌入一个浏览器,轻松地展示各种各样的网页. 1.定义一个WebView位置 <?xml version="1.0" encoding=" ...
- linux下面增加磁盘空间
1.先看看情况 [root@localhost tmp]# fdisk -l Disk /dev/sda: 3221 MB, 3221225472 bytes 255 heads, 63 sector ...
- KafkaZookeeper1-整体介绍
版本 1.0.0 概述 本文介绍了 kafka 中 zookeeper 的整体实现. 最初 kafka 使用同步的方式访问 zookeeper.但是对于 partition 个数很多的cluster, ...
- c#邮件发送服务
邮件发送服务 项目中会遇到定时给某人发送邮件的功能要求,这里是京东的一段代码,当然也是我同事找的,我记录学习一下,以免忘记. 这是解决方案 这里主要是工具:日志工具,链接数据库工具,发送邮件工具 这里 ...
- PHP简介 变量 输出
一.PHP概念 Hypertext Preprocessor 超文本预处理器,是一种开源脚本语言,语法吸收了C语言,Java,Perl的特点,用于web开发领域, PHP是将程序嵌入到Html文档中执 ...
- java.lang.NoClassDefFoundError: org/springframework/dao/support/PersistenceE解决方法
笔者是使用spring4.0时,报的错误: 原因是没有引入spring-tx-4.0.0.RELEASE.jar包,將spring-tx-4.0.0.RELEASE.jar添加到build path中 ...
- Hibernate框架学习(二)——api详解
一.Configuration对象 功能:配置加载类,用于加载主配置,orm元数据加载. //1.创建,调用空参构造(还没有读配置文件) Configuration conf=new Configur ...
- UVa 12545 Bits Equalizer【贪心】
题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作 先可以画个草图 发现需要考虑的就是 1---0 0---1 ?---0 ...