洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)
题目描述
永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛。如果从岛 aaa 出发经过若干座(含 000 座)桥可以 到达岛 bbb ,则称岛 aaa 和岛 bbb 是连通的。
现在有两种操作:
B x y 表示在岛 xxx 与岛 yyy 之间修建一座新桥。
Q x k 表示询问当前与岛 xxx 连通的所有岛中第 kkk 重要的是哪座岛,即所有与岛 xxx 连通的岛中重要度排名第 kkk 小的岛是哪座,请你输出那个岛的编号。
输入输出格式
输入格式:
第一行是用空格隔开的两个正整数 nnn 和 mmm ,分别表示岛的个数以及一开始存在的桥数。
接下来的一行是用空格隔开的 nnn 个数,依次描述从岛 111 到岛 nnn 的重要度排名。随后的 mmm 行每行是用空格隔开的两个正整数 aia_iai 和 bib_ibi ,表示一开始就存在一座连接岛 aia_iai 和岛 bib_ibi 的桥。
后面剩下的部分描述操作,该部分的第一行是一个正整数 qqq ,表示一共有 qqq 个操作,接下来的 qqq 行依次描述每个操作,操作的 格式如上所述,以大写字母 QQQ 或 BBB 开始,后面跟两个不超过 nnn 的正整数,字母与数字以及两个数字之间用空格隔开。
输出格式:
对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表示所询问岛屿的编号。如果该岛屿不存在,则输出 −1-1−1 。
输入输出样例
说明
对于 20% 的数据 n≤1000,q≤1000n \leq 1000, q \leq 1000n≤1000,q≤1000
对于 100% 的数据 n≤100000,m≤n,q≤300000n \leq 100000, m \leq n, q \leq 300000 n≤100000,m≤n,q≤300000
题解:因为只有新增的桥,我们会想到并查集,问题转化成如何求一个并查集里的k小值,怎么办呢?当然是线段树合并了!我们在将x搞成y的父亲是顺便把y的线段树合并到x上就可以啦,接着就是权值线段树查询k小值的内容,显然不用再讲了。
代码如下:
#include<bits/stdc++.h>
#define lson tr[now].l
#define rson tr[now].r
using namespace std; struct tree
{
int l,r,sum;
}tr[]; int q,n,m,cnt,im[],wim[],f[],rt[]; int push_up(int now)
{
tr[now].sum=tr[lson].sum+tr[rson].sum;
} int update(int &now,int l,int r,int pos,int val)
{
if(!now) now=++cnt;
if(l==r)
{
tr[now].sum+=val;
return ;
}
int mid=(l+r)>>;
if(pos<=mid) update(lson,l,mid,pos,val);
else update(rson,mid+,r,pos,val);
push_up(now);
} int merge(int a,int b,int l,int r)
{
if(!a) return b;
if(!b) return a;
if(l==r)
{
tr[a].sum+=tr[b].sum;
return a;
}
int mid=(l+r)>>;
tr[a].l=merge(tr[a].l,tr[b].l,l,mid);
tr[a].r=merge(tr[a].r,tr[b].r,mid+,r);
push_up(a);
return a;
} int kth(int now,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>;
if(tr[lson].sum>=k) return kth(lson,l,mid,k);
else return kth(rson,mid+,r,k-tr[lson].sum);
} int init()
{
for(int i=;i<=;i++)
{
f[i]=i;
}
} int find(int x)
{
if(f[x]==x) return x;
return f[x]=find(f[x]);
} int union_(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return ;
f[fx]=fy;
merge(rt[fy],rt[fx],,);
} int print(int now)
{
if(lson) print(lson);
if(rson) print(rson);
printf("%d ",tr[now].sum);
} int solve(int v,int k)
{
int fv=find(v),ans;
if(tr[rt[fv]].sum<k) return puts("-1"),;
else ans=kth(rt[fv],,,k);
printf("%d\n",wim[ans]);
} int main()
{
init();
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) rt[i]=i,cnt++;
for(int i=;i<=n;i++)
{
scanf("%d",&im[i]);
wim[im[i]]=i;
update(rt[i],,,im[i],);
}
int from,to;
for(int i=;i<=m;i++)
{
scanf("%d%d",&from,&to);
union_(from,to);
}
char op[];
scanf("%d",&q);
while(q--)
{
scanf("%s %d %d",op,&from,&to);
if(op[]=='Q') solve(from,to);
if(op[]=='B') union_(from,to);
}
}
洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)的更多相关文章
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- 洛谷 P3224 [HNOI2012]永无乡 解题报告
P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...
- [HNOI2012]永无乡 线段树合并
[HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- 2018.08.11 洛谷P3224 [HNOI2012]永无乡(线段树合并)
传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 ...
- 洛谷 P3224 [HNOI2012]永无乡
题面 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛 ...
- [洛谷P3224][HNOI2012]永无乡
题目大意:给你$n$个点,每个点有权值$k$,现有两种操作: 1. $B\;x\;y:$将$x,y$所在联通块合并2. $Q\;x\;k:$查询第$x$个点所在联通块权值第$k$小是哪个数 题解:线段 ...
- bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- bzoj2733: [HNOI2012]永无乡 线段树合并
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...
随机推荐
- sysbench 0.5使用手册
注意:本文刚开始只介绍了sysbench 0.5之前的版本,在了解了sysbench 0.5之后进行了补充,大部分测试和参数都是一样的,只是sysbench 0.5 在测试数据库方面更加全面丰富. 关 ...
- Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决
Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决 I. 概述 1.1 JDBC概念 JDBC(Java Database Connectivity ...
- 列名 'Discriminator' 无效 解决方案
{"列名 'Discriminator' 无效.\r\n列名 'Discriminator' 无效.\r\n列名 'Discriminator' 无效.\r\n列名 'FileUrl' 无 ...
- 蓝桥杯 生命之树【树状dp】
生命之树 在X森林里,上帝创建了生命之树. 他给每棵树的每个节点(叶子也称为一个节点)上, 都标了一个整数,代表这个点的和谐值. 上帝要在这棵树内选出一个非空节点集S, 使得对于S中的任意两个点a,b ...
- 学习笔记之Android
Android 开发专区 - 开源中国社区 http://www.oschina.net/android 探索 Android Studio | Android Studio https://deve ...
- 面试总结之数据结构(Data Structure)
常用数据结构及复杂度 http://www.cnblogs.com/gaochundong/p/3813252.html 常用数据结构的时间复杂度 Data Structure Add Find De ...
- 项目管理工具maven(一)
1 Maven的概述 1.1 依赖管理 就是对jar包的统一管理 可以节省空间 1.2 项目一键构建 编码 编译 测试(junit) 运行 打包 部署 一个 tomcat:run就能把项目 ...
- Mysql 索引优化 - 1
单表 范围查询 后面的索引会失效 双表 左右连接建立索引互相使用 三表 用小结果集驱动大表结果, 先优化括号里面的SQL, 保证JOIN被驱动的表上ON字段有索引 索引失效(常见原因) 全职匹 ...
- hive 建表导入数据
1. hive> create table wyp > (id int, name string, > age int, tel string) > ROW FORMAT DE ...
- flask test
DATABASE_URI = 'mysql://root:mhc.123@127.0.0.1/test1'