BZOJ2733: [HNOI2012]永无乡(线段树合并)
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
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
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]永无乡(线段树合并)的更多相关文章
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- bzoj2733: [HNOI2012]永无乡 线段树合并
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...
- [HNOI2012]永无乡 线段树合并
[HNOI2012]永无乡 LG传送门 线段树合并练手题,写这篇博客只是为了给我的这篇文章找个板子题. 并查集维护连通性,对于不在同一个连通块内的合并操作每次直接合并两颗线段树,复杂度\(O(n \l ...
- 【bzoj2733】[HNOI2012]永无乡 线段树合并
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)
题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接, ...
- 2733: [HNOI2012]永无乡 线段树合并
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=2733 题解: 建n棵动态开点的权值线段树,然后边用并查集维护连通性,边合并线段树维护第k重 ...
- Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...
- bzoj 2733: [HNOI2012]永无乡 -- 线段树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...
- 【BZOJ2733】【HNOI2012】永无乡 - 线段树合并
题意: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...
随机推荐
- 巧用FPGA中资源
随着FPGA的广泛应用,所含的资源也越来越丰富,从基本的逻辑单元.DSP资源和RAM块,甚至CPU硬核都能集成在一块芯片中.在做FPGA设计时,如果针对FPGA中资源进行HDL代码编写,对设计的资源利 ...
- BZOJ 1579 道路升级 Dijkstra
思路: 这道题 不能把所有边都建出来 会MLE的!!! oh gosh 其实不建所有的边 用的时候再调就行了-.(也没啥区别) //By SiriusRen #include <queue> ...
- java读取jpg图片旋转按比例缩放
//入口 public static BufferedImage constructHeatWheelView(int pageWidth, int pageHeight, DoubleHolder ...
- 定时器函数SetTimer
原文链接:http://www.cnblogs.com/zhangpengshou/archive/2009/04/05/1429770.html 一.SetTimer表示的是定义个定时器.根据定义指 ...
- 使用iVMS-4200 存储录像数据时的设置
1.安装软件时,选择:存储服务器 2.对存储服务器进行配置,具体配置见 配置手册.
- QNX与Linux两家未来有望独霸车载电子操作系统
车载电子操作系统是汽车智能化的核心,能够有效分配车机的硬件资源,对车内各种任务功能进行协同管理,并控制各项任务优先级别.常见的车载电子操作系统有:QNX.Linux(Android,AaliOS).W ...
- python3 类、对象的基础概念
类:具有相同特性和方法的抽象概念称为类 对象:从类中具体描述的一个事物称为对象 类和对象的关系:类是对象的抽象概念,对象是类的具体实例 class test001: #创建类 def __init__ ...
- 新浪新闻按keyword抓取实例
import urllib2 import requests #import MySQLdb import webbrowser import string import re from Beauti ...
- QTP校验数据库中数据后台项目
数据校验功能后台主要包含两个类:QTPCommonServlet.java和QTPCommonDao.java 当中QTPCommonServlet.java为: package com.runqia ...
- Activity中recreate方法的应用
參考两篇文章:http://blog.csdn.net/watermusicyes/article/details/47392949 http://blog.csdn.net/droyon/a ...