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

5 1
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

-1
2
5
1
2

tmd手残把rotate写错了……
中间将一个splay的点插入到另一个splay中忘了把插入的点clear……
什么鬼啊一个启发式合并的模板题为什么让我做成这样……
累觉不爱

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N (100000+100)
using namespace std;
int n,m,p;
int Root[N],num[N];
int Val[N],Size[N],Father[N],Son[N][]; int Get(int x) {return Son[Father[x]][]==x;}
void Update(int x) {Size[x]=Size[Son[x][]]+Size[Son[x][]]+;}
void Clear(int x) {num[x]=Size[x]=Father[x]=Son[x][]=Son[x][]=;}
void Rotate(int x)
{
int wh=Get(x);
int fa=Father[x],fafa=Father[fa];
if (fafa) Son[fafa][Son[fafa][]==fa]=x;
Father[fa]=x; Son[fa][wh]=Son[x][wh^];
if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
Father[x]=fafa; Son[x][wh^]=fa;
Update(fa); Update(x);
} void Splay(int x)
{
for (int fa;fa=Father[x];Rotate(x))
if (Father[fa])
Rotate(Get(x)==Get(fa)?fa:x);
Root[num[x]]=x;
} void Insert(int x,int y)//insert x to y
{
int now=Root[num[y]],fa=;
while ()
{
fa=now,now=Son[now][Val[x]>Val[now]];
if (now==)
{
Father[x]=fa;
Son[fa][Val[x]>Val[fa]]=x;
Size[x]=;
num[x]=num[y];
Update(fa);
Splay(x);
return;
}
}
} void Dfs(int x,int y)
{
if (Son[x][]) Dfs(Son[x][],y);
if (Son[x][]) Dfs(Son[x][],y);
Clear(x);
Insert(x,y);
} void Merge(int x,int y)
{
if (Size[x]>Size[y]) swap(x,y);
Dfs(x,y);
} int Findx(int now,int x)
{
while ()
if (x<=Size[Son[now][]])
now=Son[now][];
else
{
x-=Size[Son[now][]];
if (x==)
{
Splay(now);
return now;
}
x--;
now=Son[now][];
}
} int main()
{
char opt[];
int x,y;
scanf("%d%d",&n,&m);
for (int i=;i<=n;++i)
{
scanf("%d",&Val[i]);
Root[i]=num[i]=i;
Size[i]=;
}
//num表示每个点属于的树的标号,Root表示对于标号树的根
for (int i=;i<=m;++i)
{
scanf("%d%d",&x,&y);
if (num[x]!=num[y])
Merge(Root[num[x]],Root[num[y]]);
}
scanf("%d",&p);
for (int i=;i<=p;++i)
{
scanf("%s%d%d",opt,&x,&y);
if (opt[]=='Q') printf("%d\n",Size[Root[num[x]]]>=y?Findx(Root[num[x]],y):-);
if (opt[]=='B' && num[x]!=num[y]) Merge(Root[num[x]],Root[num[y]]);
}
}

2733. [HNOI2012]永无乡【平衡树-splay】的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. bzoj 2733: [HNOI2012]永无乡 -- 线段树

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

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

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

随机推荐

  1. Web前端开发工程师常用技术网站整理

    1.常用工具相关 有道云笔记 http://note.youdao.com/signIn/index.html 36镇-最好用的共享收藏夹 http://www.36zhen.com/ 浏览器同步测试 ...

  2. 算法:QQ等级换算成皇冠太阳星星月亮

    /// <summary> /// 等级换算成图标分布 /// 以QQ的形式计算 /// 2^(2*0) /1    /// 2^(2*1) /4    /// 2^(2*2) /16   ...

  3. SpringBoot 入门(一)

    1. 什么是SpringBoot? SpringBoot是一个快速开发框架,能够帮我们快速整合第三方框架(Maven依赖关系##Maven继承),完全采用注解化,简化XML配置,内置嵌入Http服务器 ...

  4. python 中迭代和遍历的区别

    什么是迭代? 迭代就是重复运行一段代码语句块的能力.分为两种方式 使用递归函数 使用循环(for 或 while 循环) 假设有个需求,要按照降序打印10以下(包括10),0 以上的整数,用递归和循环 ...

  5. Code Signal_练习题_All Longest Strings

    Given an array of strings, return another array containing all of its longest strings. Example For i ...

  6. android之在view中内嵌浏览器的方法

    我要做的一个东西是在一个页面的中间嵌入浏览器,一开始不知道从哪里开始,因为以前用的都是Textveiw或者editVeiw之类的控件,而它们并不能用来显示网页的内容,怎么办呢? 首先想到的是:是不是有 ...

  7. 导航栏布局时遇到的问题以及解决办法 css选择器优先级

    得到的导航栏效果 添加#menu ul li{width:30px;} 效果如图 将会使列表项和分隔区域的宽度同时改变因为id选择器的优先级高于类选择器,此时应该为列表项添加内联样式如图 才能得到如下 ...

  8. JavaScript 面向对象的程序设计

    面向对象(Object-oriented,OO)的语言有一个标志,那就是它们都有类的概念.而通过类可以创建任意多个具有相同属性和方法的对象.前面提到过,ECMAScript中没有类的概念,因此它的对象 ...

  9. ubuntu下创建虚拟python3开发环境

    友情链接:ubuntu16.04下安装python3+创建虚拟python3开发环境 1.为什么要创建python3虚拟开发环境? /********************************* ...

  10. 合理选择css3动画实现方式

    使用css3实现动画,比js控制DOM属性的方式要高效很多.流畅很多,主要分transition和animation两大方式. transition适用于一次性变换 animation适用于循环动画和 ...