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

解题思路:

权值线段树合并,将并查集连接时将线段树合并,最后查询根节点的值就好了

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
struct trnt{
int ls;
int rs;
int wgt;
}tr[],str;
int fa[];
int imp[];
int root[];
int island[];
int siz;
int n,m;
int bin[];
int top;
char cmd[];
void pushup(int spc)
{
if(!spc)
return ;
tr[spc].wgt=tr[tr[spc].ls].wgt+tr[tr[spc].rs].wgt;
return ;
}
int finf(int x)
{
return x==fa[x]?x:fa[x]=finf(fa[x]);
}
int new_p(void)
{
int ans;
if(top)
ans=bin[top--];
ans=++siz;
tr[ans]=str;
return ans;
}
void del(int &spc)
{
bin[++top]=spc;
spc=;
return ;
}
void build(int &spc,int l,int r,int pos)
{
if(!spc)
spc=new_p();
tr[spc].wgt++;
if(l==r)
return ;
int mid=(l+r)>>;
if(pos<=mid)
build(tr[spc].ls,l,mid,pos);
else
build(tr[spc].rs,mid+,r,pos);
return ;
}
int merge(int spc1,int spc2,int l,int r)
{
if(!spc1||!spc2)
return spc1+spc2;
int spc=new_p();
if(l==r)
{
tr[spc].wgt=tr[spc1].wgt+tr[spc2].wgt;
return spc;
}
int mid=(l+r)>>;
tr[spc].ls=merge(tr[spc1].ls,tr[spc2].ls,l,mid);
tr[spc].rs=merge(tr[spc1].rs,tr[spc2].rs,mid+,r);
pushup(spc);
del(spc1);
del(spc2);
return spc;
}
int kth(int l,int r,int k,int spc)
{
if(l==r)
return l;
int mid=(l+r)>>;
if(tr[spc].wgt<k)
return -;
if(tr[tr[spc].ls].wgt>=k)
return kth(l,mid,k,tr[spc].ls);
else
return kth(mid+,r,k-tr[tr[spc].ls].wgt,tr[spc].rs);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&imp[i]);
fa[i]=i;
build(root[i],,n,imp[i]);
island[imp[i]]=i;
}
for(int i=;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
int fx=finf(a);
int fy=finf(b);
if(a!=b)
{
fa[fx]=fy;
root[fy]=merge(root[fx],root[fy],,n);
}
}
int q;
scanf("%d",&q);
while(q--)
{
scanf("%s",cmd+);
int x,y;
scanf("%d%d",&x,&y);
if(cmd[]=='B')
{
int fx=finf(x);
int fy=finf(y);
if(fy!=fx)
{
fa[fx]=fy;
root[fy]=merge(root[fx],root[fy],,n);
}
}else{
int f=finf(x);
int no=kth(,n,y,root[f]);
if(no==-)
printf("%d\n",-);
else
printf("%d\n",island[no]);
}
}
return ;
}

BZOJ2733: [HNOI2012]永无乡(线段树合并)的更多相关文章

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

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

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

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

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

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

  4. 【bzoj2733】[HNOI2012]永无乡 线段树合并

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

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

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

  6. 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)

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

  7. 2733: [HNOI2012]永无乡 线段树合并

    题目: https://www.lydsy.com/JudgeOnline/problem.php?id=2733 题解: 建n棵动态开点的权值线段树,然后边用并查集维护连通性,边合并线段树维护第k重 ...

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

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

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

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

  10. 【BZOJ2733】【HNOI2012】永无乡 - 线段树合并

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

随机推荐

  1. 解决Struts中文乱码问题总结

    在进行struts开发的过程中.总也是出现非常多的乱码问题.但归根究竟,也仅仅是下面三种情况:  ㈠页面显示中文乱码  ㈡传递參数中文乱码  ㈢国际化资源文件乱码  以下就这三中情况介绍怎么在详细项目 ...

  2. 《Spring技术内幕》笔记-第四章 Spring MVC与web环境

    ​上下文在web容器中的启动 1,IoC容器的启动过程 IoC的启动过程就是建立上下文的过程.该上下文是与ServletContext相伴.在Spring中存在一个核心控制分发器,Dispatcher ...

  3. VB.NET中文双引号的处理方法

    相信朋友们也都碰到了这样的问题了,VS的IDE会不分青红皂白的把中文双引号变成英文的双引号,当然可以通过关闭自动重排功能来回避这个问题,但不是一个好的解决办法,以下这个方式不错: 如果在实际的使用中我 ...

  4. jython awt demo

    jython awt demo : """\ Create a panel showing all of the colors defined in the pawt.c ...

  5. js library 集合

    js library 集合 查看已经开源的js library https://cdnjs.com/

  6. js中迭代的常用几种方法

    var arr = [1,3,2,5,3]; //forEach 两个参数,第一个为数组内容,第二个为数组下标arr.forEach(function(item,index) { console.lo ...

  7. Django_shell命令操作

  8. 紫书 习题 10-25 UVa 1575 (有重复元素的全排列+暴搜)

    我一开始以为有什么很牛逼的方法来做,然后一直没有思路 后来看了https://blog.csdn.net/zju2016/article/details/78562932的博客 竟然是暴搜?????? ...

  9. CSUOJ 1635 Restaurant Ratings

    1635: Restaurant Ratings Time Limit: 1 Sec  Memory Limit: 128 MB Description A famous travel web sit ...

  10. java同步包种ArrayBlockingQueue类的分析与理解

    前言: ArrayBlockingQueue类是一个堵塞队列.重要用于多线程操作的条件. 一,官方解释 一个建立在数组之上被BlockingQueue绑定的堵塞队列.这个队列元素顺序是先进先出.队列的 ...