2733: [HNOI2012]永无乡

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3955  Solved: 2112
[Submit][Status][Discuss]

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
  这道题当时第一眼觉得像是图论tarjan题,然后看到了求排名的操作,这就不得不考虑平衡树了,由于平衡树我只会SPLAY,不会无旋TREAP所以我就只讲SPLAY的了。
  这道题想到平衡树后就开始想合并操作,如果暴力合并最坏貌似是炸翻天的,一开始以为有什么神奇的打法,比如区间插入还自带平衡的黑科技之类的,结果同桌告诉我是启发式合并。所谓启发式合并就是暴力合并,只是有一个几乎所有人都想的到的剪枝,让小项去合并大项,时间自然会小不少。
  所以对于每一次合并我们只是dfs一边当前的小子树,然后就暴力合并就好了,其他操作照常。
 #pragma GCC optimze("O3")
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#define N 100004
using namespace std;
int n,m,q,f[N],fa[N],size[N],ch[N][],data[N];
int find(int x)
{
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
bool get(int x)
{
return x==ch[fa[x]][];
}
void update(int x)
{
if(x)
{
size[x]=;
if(ch[x][]) size[x]+=size[ch[x][]];
if(ch[x][]) size[x]+=size[ch[x][]];
}
}
void rotate(int x)
{
int faa=fa[x],ffa=fa[fa[x]];
int op=get(x);
ch[faa][op]=ch[x][op^];
fa[ch[faa][op]]=faa;
ch[x][op^]=faa;
fa[faa]=x;
fa[x]=ffa;
if(ffa)ch[ffa][ch[ffa][]==faa]=x;
update(faa);
update(x);
return;
}
void splay(int x)
{
for(int ff;ff=fa[x];rotate(x))
{
if(fa[ff])
rotate((get(x)==get(ff))?ff:x);
}
return;
}
int lart;
void insert(int x,int now,int faa)
{ if(now==)
{
fa[x]=faa;
if(data[x]<data[faa]) ch[faa][]=x;
else ch[faa][]=x;
splay(x);
lart=x;
return;
}
if(data[x]<data[now])insert(x,ch[now][],now);
else insert(x,ch[now][],now);
}
void dfs(int x,int y)
{
int le=ch[x][],ri=ch[x][];
ch[x][]=ch[x][]=;
insert(x,y,);
if(le)dfs(le,lart);
if(ri)dfs(ri,lart);
}
int get_rank(int x,int la)
{
if(la==size[ch[x][]]+)
return x;
if(la<=size[ch[x][]])
return get_rank(ch[x][],la);
else
return get_rank(ch[x][],la-size[ch[x][]]-);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&data[i]);
f[i]=i;size[i]=;
}
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int aa=find(x),bb=find(y);
if(aa==bb)continue;
f[aa]=bb;
splay(x),splay(y);
if(size[x]>size[y])
dfs(y,x);
else
dfs(x,y);
}
scanf("%d",&q);
char b[];
for(int i=;i<=q;i++)
{
scanf("%s",b);
int x,y;
scanf("%d%d",&x,&y);
if(b[]=='B')
{
int aa=find(x),bb=find(y);
if(aa==bb)continue;
f[aa]=bb;
splay(x),splay(y);
if(size[x]>size[y])
dfs(y,x);
else
dfs(x,y);
}
else
{
splay(x);
if(size[x]<y)printf("-1\n");
else
{
printf("%d\n",get_rank(x,y));
}
}
}
return ;
}

Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并的更多相关文章

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

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

  2. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

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

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

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

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

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

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

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

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

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

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

  8. BZOJ2733 永无乡 【splay启发式合并】

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 4190  Solved: 2226 [Submit][Sta ...

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

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

随机推荐

  1. 图像滤镜艺术--PS平均(滤镜-模糊-平均)效果

    原文:图像滤镜艺术--PS平均(滤镜-模糊-平均)效果 本文介绍PS中滤镜-模糊-平均模糊的效果实现: 这个效果很简单,原理如下: 1,统计全图像素的R,G,B值得和sumR,sumG,sumB; 2 ...

  2. 微信小程序把玩(二十九)video组件

    原文:微信小程序把玩(二十九)video组件 视频播放组件与图片加载组件也没啥差别,使用起来也没啥注意的 重要属性: wxml <!--监听button点击事件--> <button ...

  3. 关于jquery.fileupload结合PHP上传图片的开发用法流程

    这阵子做了一个项目,涉及到了图片上传,以往用的都是uploadify这个插件,感觉它在PC上的使用还是很强大的, 不过最近这个项目涉及到了移动端的上传,其实uploadify也可以,但是他有一个 up ...

  4. linux输出信息调试信息重定向

    最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0).因为后期要使用ttySAC0作为上层应用通信 ...

  5. qt获取网络ip地址的类

    最近在学习qt网络编程,基于tcp和udp协议. 看了一些别人的程序和qt4自带的例子,困扰我最大的问题就是获取ip的类,总结起来还挺多的. 主要介绍常用的QtNetwork Module中的QHos ...

  6. vue+element——父级元素fixed,遮罩会在上方

    前言 这种场景还是蛮场景的 一个共用的head组件,组件里面通常是当前系统登录账号名 退出登录 修改密码这样的弹框 但是现在我又想head不跟着main内容上下滑动.所以用了fixed 定位. 问题来 ...

  7. 有关Html页面节点的简单理解

    这是之前研究web前端的一点经验,主要针对刚入门还没怎么研究的朋友. 因为我发现我在用js,css参与过网站开发项目后仍然没有理解文本节点与普通节点的差别,所以记下来拿来分享一下. 先上结论:< ...

  8. jmeter模拟spike测试(尖峰测试)

    概述 尖峰测试(Spike testing)在性能测试中属于压力测试的一个子集.指的是在某一瞬间或者多个频次下用户数和压力陡然增加的场景. 为了验证我们的网站在访问用户急剧增加的情况下,或者短时间内反 ...

  9. 前后端开发(2):浏览器与PHP程序的交互

    上一节介绍怎么在mac电脑上启用PHP程序,并且演示了一个简单的例子,这个例子运行时,涉及了浏览器.apache以及PHP程序的交互,这三者的关系大概是这样的: 一般来说,浏览器(或者类似功能的程序) ...

  10. 什么是BFC? CSS 如何使用伪元素清除浮动?

    .BFC概念: 块级格式化上下文,是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响. 我们先了解一个名词:BFC(block formatting c ...