[HNOI2012]永无乡
题目描述
永无乡包含 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。
输入输出样例
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
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]永无乡的更多相关文章
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1167 Solved: 607[Submit][Status ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- B20J_2733_[HNOI2012]永无乡_权值线段树合并
B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...
- 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡
题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...
- bzoj2733: [HNOI2012]永无乡 启发式合并
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec ...
- [HNOI2012]永无乡 线段树合并
[HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...
- bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)
[HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...
- bzoj 2733: [HNOI2012]永无乡 -- 线段树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...
随机推荐
- 20162308 实验二《Java面向对象程序设计》实验报告
20162308 实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...
- DML数据操作语言之查询(二)
当我们查询出了N条记录之后 ,我们知道一共是几条记录,或者这些记录某一字段(列值)的最大值,最小值,平均值等,就可以使用聚合函数. 1.聚合函数 聚合函数会将null 排除在外.但是count(*)例 ...
- centos 开放端口
1.修改文件/etc/sysconfig/iptables [root@zsq ~]# cd /etc/sysconfig/[root@zsq sysconfig]# vi iptables 文件内容 ...
- 从PRISM开始学WPF(三)Prism-Region?
从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...
- V7000数据恢复(存储文件系统损坏)案例_北亚数据恢复
我们今天介绍的数据恢复案例是一起 v7000存储文件系统损坏导致的数据丢失,首先简单介绍一下设备基本情况:发生文件系统损坏的是一台挂载在Windows2003服务器上的v7000存储,划分了一个容量为 ...
- 一张图说明 Web Api 参数绑定默认规则
请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...
- SpringCloud用户自定义配置信息的定义和查看
一.概念 在SpringCloud项目中,用户自己定义的配置信息也可以放在application.*,需要以 info打头,以便使用公用基础设施 /info 查看! 本文讲解基于 ConfigServ ...
- 爬虫必备 User-Agent 列表
USER_AGENTS = [ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR ...
- 【webGL入门2】点线面的绘制
用js绘制webGL的点: THREE.Vector3 = function ( x, y, z ) { //用THREE声明的变量都是全局变量.this.x = x || 0;this.y = y ...
- 复习HTML+CSS(5)
n <meta>标记 <meta>的主要作用,是提供网页的源信息.比如:指定网页的搜索关键字 <meta>标记有两个属性:http-equiv和name. 1. ...