题目描述

永无乡包含 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 。

输入输出样例

输入样例#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

说明

对于 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]永无乡(线段树合并+并查集)的更多相关文章

  1. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  2. 洛谷 P3224 [HNOI2012]永无乡 解题报告

    P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 ...

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

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

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

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

  5. 2018.08.11 洛谷P3224 [HNOI2012]永无乡(线段树合并)

    传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 ...

  6. 洛谷 P3224 [HNOI2012]永无乡

    题面 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛 ...

  7. [洛谷P3224][HNOI2012]永无乡

    题目大意:给你$n$个点,每个点有权值$k$,现有两种操作: 1. $B\;x\;y:$将$x,y$所在联通块合并2. $Q\;x\;k:$查询第$x$个点所在联通块权值第$k$小是哪个数 题解:线段 ...

  8. bzoj 2733 : [HNOI2012]永无乡 (线段树合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  9. bzoj2733: [HNOI2012]永无乡 线段树合并

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...

随机推荐

  1. Linux学习系列之Nginx调优实战

    Nginx配置文件性能微调 全局的配置 user www-data; pid /var/run/nginx.pid; worker_processes auto; worker_rlimit_nofi ...

  2. 第十届蓝桥杯 试题 E: 迷宫

    试题 E: 迷宫 本题总分:15 分 [问题描述] 下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方. 010000 000100 001001 110000 迷 ...

  3. C++ 函数特性_函数重载

    函数重载 在相同作用域内 用同一函数名定义的多个函数: 参数个数和参数类型不同 int getMax(int x,int y,int z) // 函数名相同都是 getMax() { // to do ...

  4. 中信信用卡淘气金卡,V金卡,大众点评金卡,易卡白金卡

    中信 | 谈谈经典多倍积分卡:易卡&悦卡(超详细+图解+思考)! http://www.flyertea.com/thread-1972766-1-1.html 易卡积分测试,购物/机票/外卖 ...

  5. Autofac容器使用属性进行WebApi自动注入

    背景 使用Autofac进行依赖注入时,经常遇到的场景是在容器中进行类似如下代码的注入操作: builder.RegisterType<BackInStockSubscriptionServic ...

  6. uedit富文本编辑器及图片上传控件

    微力后台 uedit富文本编辑器及文件上传控件的使用,无时间整理,暂略,参考本地代码.能跑起来.

  7. 5_bootstrap之响应式布局|列表|按钮

    5.响应式工具 为针对性地在移动页面上展示和隐藏不同的内容,bootStrap提供响应式工具. 可以让开发人员通过该工具决定,在何种屏幕尺寸下,隐藏或者显示某些元素 帮助手册位置:全局CSS样式--- ...

  8. sqlplus rlwrap readline

  9. mybatis 学习五 二级缓存不推荐使用

    mybatis 二级缓存不推荐使用 一 mybatis的缓存使用. 大体就是首先根据你的sqlid,参数的信息自己算出一个key值,然后你查询的时候,会先把这个key值去缓存中找看有没有value,如 ...

  10. verilog 计算机网络 仿真 激励 pcap

    做verilog网络逻辑时,需要产生正确的数据包格式激励,手写激励真烦人,现在让testbench读取pcap文件,则可以精确还原数据包的bit与时序,省去了一大批麻烦 1.设计读取逻辑 `times ...