题目链接: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+启发式合并)的更多相关文章

  1. 洛谷 P3224 [HNOI2012]永无乡 解题报告

    P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...

  2. [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并

    好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...

  3. 2733. [HNOI2012]永无乡【平衡树-splay】

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

  4. [HNOI2012]永无乡 线段树合并

    [HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...

  5. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  6. Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

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

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

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

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

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

  9. Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...

随机推荐

  1. linux 下面avr开发环境的安装

    (1)安装开发工具链 yum install avr-* 会安装以下的工具 avr-gcc-4.7.2-1.fc17.i686avr-libc-1.8.0-2.fc17.noarchavr-binut ...

  2. JStorm中的并行( parallelismction )介绍

    JStorm中的并行( parallelismction )介绍 JStrom中.一个计算任务通过多台机器使得计算分解为多个独立并行执行在集群内执行的任务(tasks).从而得到水平扩展. JStor ...

  3. leetcode 题解 || Longest Common Prefix 问题

    problem: Write a function to find the longest common prefix string amongst an array of strings. 寻找 0 ...

  4. 什么是域名的TTL值? ——一条域名解析记录在DNS缓存服务器中的存留时间

    什么是域名的TTL值? 转自:http://hizip.net/index.php/archives/20/TTL(Time-To-Live),就是一条域名解析记录在DNS服务器中的存留时间.当各地的 ...

  5. 用exp命令按用户导出的DMP文件缺少表,某些表是空表

    1.用以下这句查找空表并生成执行命令 select 'alter table '||table_name||' allocate extent;' from user_tables where num ...

  6. Java数据库连接——PreparedStatement的使用

    首先了解Statement和PreparedStatement的区别: 由此可见,一般使用PreparedStatement. 操作数据库SU(Course表),其中Course属性有Cno,Cnam ...

  7. oc消息转发机制本质

    第一级转发:主体不变,动态添加对应函数: 第二级转发:函数不变,切换接收主体: 第三极转发:函数签名不变,主体和函数都有可能变化: 1.使用函数的动态添加技术: 2.使用的类似is-a swzzing ...

  8. 路飞学城Python-Day11

    [44.函数-生成器] 需求:有一个列表 [0,1,2,3,4,5,6,7,8,9],对这个列表循环+1 li = [0,1,2,3,4,5,6,7,8,9] li = map(lambda x:x+ ...

  9. Python学习---Day96

    转载:http://www.cnblogs.com/wupeiqi/articles/6229292.html Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可 ...

  10. 全国所有省市县地理坐标Json格式

    https://www.cnblogs.com/yzbubble/p/7707129.html