[Luogu 3224] HNOI2012 永无乡

<题目链接>


特别水一个平衡树题。

不认真的代价是调试时间指数增长。

我写的 SBT,因为 Treap 的 rand() 实在写够了。

用并查集维护这些点的关系,然后启发式暴力合并,以及找第 \(k\) 小。

就是把子树较小的并到较大的里,一个一个点插入。

因为要插入新的点,给 SBT 预留的空间要大一些。(我试过只改变原来的点的信息,结果失败了。)

SBT 需要开的空间为 \(MAXN+MAXM\),因为 \(n\) 个点,每个点最多被插入 \(m\) 次。

就这样。

表白一万次 SBT 的 Maintain 操作代码,超优美的qwq。

#include <algorithm>
#include <cstdio>
#include <cstring>
using std::swap;
const int MAXN=100010,MAXM=400010;
int n,m,q;
class UFS
{
public:
void Init(int i)
{
f[i]=i;
}
int Find(int x)
{
return x==f[x] ? f[x] : f[x]=Find(f[x]);
}
void Merge(int x,int y)
{
f[Find(y)]=Find(x);
}
private:
int f[MAXN];
}S;
class SBT
{
public:
SBT(int cnt=0):cnt(cnt){}
void Init(void)
{
for(int i=1,x;i<=n;++i)
{
scanf("%d",&x);
S.Init(i),s[rt[i]=++cnt]=node(x,i,1);
}
}
void Bridge(int x,int y)
{
int a=S.Find(x),b=S.Find(y);
if(a==b)
return;
if(s[rt[a]].size>s[rt[b]].size)
S.Merge(a,b),Merge(rt[a],b);
else
S.Merge(b,a),Merge(rt[b],a);
}
int FindKth(int x,int k)
{
return k>s[x=rt[S.Find(x)]].size ? -1 : Find(x,k);
}
private:
int cnt,rt[MAXN];
struct node
{
int v,num,size,c[2];
node(int v=0,int num=0,int size=0):v(v),num(num),size(size)
{
memset(c,0,sizeof c);
}
}s[MAXM];
void Update(int i)
{
s[i].size=s[s[i].c[0]].size+s[s[i].c[1]].size+1;
}
void Rotate(int &i,bool p)
{
int t=s[i].c[!p];
s[i].c[!p]=s[t].c[p],s[t].c[p]=i;
Update(i),Update(i=t);
}
void Maintain(int &i,bool p)
{
int t=s[s[i].c[!p]].size;
if(t<s[s[s[i].c[p]].c[p]].size)
Rotate(i,!p);
else if(t<s[s[s[i].c[p]].c[!p]].size)
Rotate(s[i].c[p],p),Rotate(i,!p);
else
return;
Maintain(s[i].c[0],0),Maintain(s[i].c[1],1),Maintain(i,0),Maintain(i,1);
}
void Insert(int &i,int x,int num)
{
if(!i)
{
s[i=++cnt]=node(x,num,1);
return;
}
++s[i].size;
bool t=x>s[i].v;
Insert(s[i].c[t],x,num);
Maintain(i,t);
}
void Merge(int &x,int &y)
{
if(!y)
return;
Insert(x,s[y].v,s[y].num),Merge(x,s[y].c[0]),Merge(x,s[y].c[1]);
}
int Find(int i,int x)
{
int t;
while(x!=(t=s[s[i].c[0]].size+1))
if(x<t)
i=s[i].c[0];
else
x-=t,i=s[i].c[1];
return s[i].num;
}
}T;
int main(int argc,char *argv[])
{
scanf("%d %d",&n,&m);
T.Init();
for(int i=1,x,y;i<=m;++i)
{
scanf("%d %d",&x,&y);
T.Bridge(x,y);
}
scanf("%d",&q);
for(int i=1,x,y;i<=q;++i)
{
char c;
scanf("\n%c %d %d",&c,&x,&y);
if(c=='B')
T.Bridge(x,y);
else
printf("%d\n",T.FindKth(x,y));
}
return 0;
}

谢谢阅读。

[Luogu 3224] HNOI2012 永无乡的更多相关文章

  1. 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡

    题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...

  2. 洛谷.3224.[HNOI2012]永无乡(Splay启发式合并)

    题目链接 查找排名为k的数用平衡树 合并时用启发式合并,把size小的树上的所有节点插入到size大的树中,每个节点最多需要O(logn)时间 并查集维护连通关系即可 O(nlogn*insert t ...

  3. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  4. bzoj 2733: [HNOI2012]永无乡 离线+主席树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1167  Solved: 607[Submit][Status ...

  5. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

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

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

  7. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

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

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

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

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

随机推荐

  1. oracle数据库之PL/SQL 流程控制语句

    介绍 PL/SQL 的流程控制语句, 包括如下三类: 1.控制语句: IF 语句 2.循环语句: LOOP 语句, EXIT 语句 3.顺序语句: GOTO 语句, NULL 语句 一 条件语句 IF ...

  2. (十一)instanceof 和 getclass 的区别

    判断两个对象是否为同一类型,时常用到getclass 和 instanceof ,而这两个函数又是时常让人混淆.下面从一个例子说明两者的区别: public class Test_drive { pu ...

  3. Qt Creator子目录项目-类似VS解决方案

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt Creator子目录项目-类似VS解决方案     本文地址:http://techie ...

  4. PAT L2-028 秀恩爱分得快

    https://pintia.cn/problem-sets/994805046380707840/problems/994805054698012672 古人云:秀恩爱,分得快. 互联网上每天都有大 ...

  5. HDU 2114 Calculate S(n)

    http://acm.hdu.edu.cn/showproblem.php?pid=2114 Problem Description Calculate S(n). S(n)=13+23 +33 +. ...

  6. CCS3 动画-鼠标放上去放大背景图片

    ---〉 效果如上,一个简单的过渡放大效果, <!DOCTYPE HTML> <html> <body> <style> #test{ width:30 ...

  7. java从远程服务器获取PDF文件并后台打印(使用pdfFox)

    一.java原生方式打印PDF文件 正反面都打印,还未研究出只打印单面的方法,待解决 public static void printFile(String path) throws Exceptio ...

  8. Codeforces 498B Name That Tune

    不想说啥了…这是我被卡常数卡得最惨的一次… 首先根据期望的线性性,我们考虑每首歌能够被认出来的概率,也就是每首歌对答案贡献的期望.那么定义F[i]为第i首歌被认出来的概率是做不了的,自然想到F[i][ ...

  9. 【bzoj4326】[NOIP2015]运输计划 二分答案+LCA

    题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...

  10. Django 2.0 学习(10):Django 定制化

    定制化admin表单 通过使用admin.site.register(Question)注册Question模型,Django可以构造默认的表单.通常,可以通过对象的注册机制来告诉Django我们想要 ...