题目描述

永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。

现在有两种操作:

B x y 表示在岛 x 与岛 y 之间修建一座新桥。

Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。

输入输出格式

输入格式:

输入文件第一行是用空格隔开的两个正整数 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

输出格式:

对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。

输入输出样例

输入样例#1:

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
输出样例#1:

-1
2
5
1
2
题解:
splay+并查集
并查集判断两点是否联通,每个节点对应一个平衡树
splay用启发式合并,通过线段树思想和调整顺序可以做到不用旋转
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=,MAXM=;
int tot2,tot1,s[MAXN],pre[MAXM],ch[MAXM][],key[MAXM];
int size[MAXM],root[MAXN],n,m,set[MAXN],a[MAXN],sz,id[MAXN];
void NewNode(int &x,int fa,int k)
{
if (tot2) x=s[tot2--];
else x=++tot1;
key[x]=k;
size[x]=;
pre[x]=fa;
ch[x][]=ch[x][]=;
}
int find(int x)
{
if (set[x]!=x) set[x]=find(set[x]);
return set[x];
}
void pushup(int x)
{
int lson=ch[x][],rson=ch[x][];
size[x]=size[lson]+size[rson];
}
void insert(int &x,int l,int r,int d)
{
x=++sz;
if (l==r)
{
size[x]=;
return;
}
int mid=(l+r)>>;
if(d<=mid) insert(ch[x][],l,mid,d);
else insert(ch[x][],mid+,r,d);
pushup(x);
}
int merge(int x,int y)
{
if (!x) return y;
if (!y) return x;
ch[x][]=merge(ch[x][],ch[y][]);
ch[x][]=merge(ch[x][],ch[y][]);
pushup(x);
return x;
}
int query(int x,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>;
if(size[ch[x][]]>=k) return query(ch[x][],l,mid,k);
else return query(ch[x][],mid+,r,k-size[ch[x][]]);
}
void erase(int r)
{
if (!r) return ;
s[++tot2]=r;
erase(ch[r][]);
erase(ch[r][]);
}
void bridge_union(int x,int y)
{
int l=find(x),r=find(y);
if (l!=r)
{
if (size[root[l]]<size[root[r]]) swap(l,r);
set[r]=l;size[root[l]]+=size[root[r]];
merge(root[l],root[r]);
erase(root[r]);
}
}
char get_op()
{
char ch=getchar();
while (ch!='B'&&ch!='Q') ch=getchar();
return ch;
}
int main()
{int i,j,x,y,q,opt;
cin>>n>>m;
for (i=;i<=n;i++)
{
scanf("%d",&a[i]);
id[a[i]]=i;
set[i]=i;
}
for (i=;i<=n;i++)
insert(root[i],,n,a[i]);
for (i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
bridge_union(x,y);
}
cin>>q;
for (i=;i<=q;i++)
{
opt=get_op();
scanf("%d%d",&x,&y);
if (opt=='Q')
{
int l=find(x);
if (size[root[l]]<y) printf("-1\n");
else
printf("%d\n",id[query(root[l],,n,y)]);
}
else
{
bridge_union(x,y);
}
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)

    [HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...

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

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

随机推荐

  1. 第二次作业之微信小程序

    2.1 介绍产品相关信息 你选择的产品是? 微信小程序 为什么选择该产品作为分析? 在等待了1年多以后,小程序终于在今年初上线,即速应用在H5领域的累计,便承接在小程序上.8月7日,即速应用的用户微信 ...

  2. 201621123062《java程序设计》第八周作业总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 思维导图: 2. 书面作业 2.1ArrayList代码分析 2.1.1 解释ArrayList的contains源代码 源 ...

  3. 算法——算法时间复杂度的计算和大O阶的推导

    在算法分析中,我们将语句总的执行次数记为T(n)进而分析T(n)随n的变化情况确认T(n)的数量级.一般情况下,T(n)随n增大变化最缓慢的算法为最优算法. 根据定义,T(n)的求法是很简单的,也就是 ...

  4. 201621123031 《Java程序设计》第10周学习总结

    作业10-异常 1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 1.捕捉异常 Java中的异常捕获结构由try.catch和finally三个部分组成.其中try语句 ...

  5. iOS极光推送SDK的使用流程

    一.极光推送简介 极光推送是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,整合了iOS.Android和WP平台的统一推送服务.使用起来方便简单,已于集成,解决了原生远程推送繁 ...

  6. Flask 扩展 HTTP认证

    Restful API不保存状态,无法依赖Cookie及Session来保存用户信息,自然也无法使用Flask-Login扩展来实现用户认证.所以这里,我们就要介绍另一个扩展,Flask-HTTPAu ...

  7. Flask 学习 五 电子邮件

    pip install mail from flask_mail import Mail # 邮件配置 app.config['MAIL_SERVER']='smtp.qq.com' app.conf ...

  8. bzoj千题计划276:bzoj4515: [Sdoi2016]游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=4515 把lca带进式子,得到新的式子 然后就是 维护树上一次函数取min 一个调了一下午的错误: 当 ...

  9. bzoj 4399 魔法少女LJJ

    4399: 魔法少女LJJ Time Limit: 20 Sec  Memory Limit: 162 MBhttp://www.lydsy.com/JudgeOnline/problem.php?i ...

  10. 【译】Gradle 的依赖关系处理不当,可能导致你编译异常

    文章 | Ashesh Bharadwaj 翻译 | 承香墨影 授权 承香墨影 翻译.编辑并发布 在 Android Studio 中,Gradle 构建过程对于开发者来说,很大程度上是抽象的.作为一 ...