【bzoj3545】[ONTAK2010]Peaks 线段树合并
【bzoj3545】[ONTAK2010]Peaks
Description
在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。
Input
第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。
Output
对于每组询问,输出一个整数表示答案。
Sample Input
1 2 3 4 5 6 7 8 9 10
1 4 4
2 5 3
9 8 2
7 8 10
7 1 4
6 7 1
6 4 8
2 1 5
10 8 10
3 4 7
3 4 6
1 5 2
1 5 6
1 5 8
8 9 2
Sample Output
1
-1
8
HINT
【数据范围】
N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。
题解
离散后排序,维护加边顺序,然后就是线段树合并了,权值线段树。
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio> #define N 100007
#define M 500007
#define ll long long
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch>''||ch<''){if (ch=='-') f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,q,sz;
int fa[N],rt[N],ans[M],disc[N],h[N];
int siz[M*],ls[M*],rs[M*];
struct Node
{
int x,y,difficulty;
}a[M];
struct Date
{
int x,limit,k,id;
}b[M]; int find(int num)
{
if (fa[num]!=num) fa[num]=find(fa[num]);
return fa[num];
}
bool cmp(Node x,Node y)
{
return x.difficulty<y.difficulty;
}
bool cmp1(Date x,Date y)
{
return x.limit<y.limit;
} int merge(int x,int y)
{
if (!x)return y;
if (!y)return x;
if (!ls[x]&&!rs[x])
{
siz[x]=siz[x]+siz[y];
return x;
}
ls[x]=merge(ls[x],ls[y]);
rs[x]=merge(rs[x],rs[y]);
siz[x]=siz[ls[x]]+siz[rs[x]];
return x;
}
void ins(int &p,int l,int r,int z)
{
if (!p)p=++sz,siz[p]=;
if (l==r) return;
int mid=(l+r)>>;
if (z<=mid)ins(ls[p],l,mid,z);
else ins(rs[p],mid+,r,z);
}
int query(int p,int l,int r,int rank)
{
if (l==r) return l;
int mid=(l+r)>>;
if (rank<=siz[ls[p]])return query(ls[p],l,mid,rank);
else return query(rs[p],mid+,r,rank-siz[ls[p]]);
}
void solve()
{
int now=;
for (int i=;i<=q;i++)
{
while(now<m&&a[now+].difficulty<=b[i].limit)
{
int x=find(a[now+].x),y=find(a[now+].y);
if (x!=y)
{
fa[y]=x;
rt[x]=merge(rt[x],rt[y]);
}
now++;
}
int x=find(b[i].x);
if (siz[rt[x]]<b[i].k) ans[b[i].id]=-;
else ans[b[i].id]=disc[query(rt[x],,n,siz[rt[x]]-b[i].k+)];
}
for (int i=;i<=q;i++)
printf("%d\n",ans[i]);
}
int main()
{
freopen("fzy.in","r",stdin);
freopen("fzy.out","w",stdout); n=read(),m=read(),q=read();
for (int i=;i<=n;i++)
disc[i]=h[i]=read(),fa[i]=i;
sort(disc+,disc+n+);
for (int i=;i<=n;i++)
h[i]=lower_bound(disc+,disc+n+,h[i])-disc;
for (int i=;i<=n;i++)
ins(rt[i],,n,h[i]); for (int i=;i<=m;i++)
a[i].x=read(),a[i].y=read(),a[i].difficulty=read();
sort(a+,a+m+,cmp);
for (int i=;i<=q;i++)
b[i].x=read(),b[i].limit=read(),b[i].k=read(),b[i].id=i;
sort(b+,b+q+,cmp1);
solve();
}
【bzoj3545】[ONTAK2010]Peaks 线段树合并的更多相关文章
- BZOJ.3545.[ONTAK2010]Peaks(线段树合并)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...
- Peaks 线段树合并
Peaks 线段树合并 \(n\)个带权值\(h_i\)山峰,有\(m\)条山峰间双向道路,\(q\)组询问,问从\(v_i\)开始只经过\(h_i\le x\)的路径所能到达的山峰中第\(k\)高的 ...
- bzoj3545 Peaks 线段树合并
离线乱搞... 也就是一个线段树合并没什么 #include<algorithm> #include<iostream> #include<cstring> #in ...
- 【线段树合并】bzoj3545: [ONTAK2010]Peaks
1A还行 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问, ...
- [BZOJ3545] [ONTAK2010]Peaks(线段树合并 + 离散化)
传送门 由于困难值小于等于x这个很恶心,可以离线处理,将边权,和询问时的x排序. 每到一个询问的时候,将边权小于等于x的都合并起来再询问. .. 有重复元素的线段树合并的时间复杂度是nlog^2n # ...
- BZOJ3545 Peaks 离线处理+线段树合并
题意: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...
- bzoj3545: [ONTAK2010]Peaks 重构树 主席树
题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...
- 线段树合并&&启发式合并笔记
这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息. 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直 ...
- bzoj3545 [ONTAK2010]Peaks、bzoj3551 [ONTAK2010]Peaks加强版
题目描述: bzoj3545,luogu bzoj3551 题解: 重构树+线段树合并. 可以算是板子了吧. 代码(非强制在线): #include<cstdio> #include< ...
随机推荐
- 连接MongoDB数据库的配置说明
- MS SQL生成数据库字典脚本
开发一个项目时都会有一个蛋疼的问题——写数据库需求文档,然后根据这个文档来建数据库,如果后来需求改了,要改数据库还要改文档,有时忙着忙着就忘改了,导致文档是过期的.那么我们自己写个脚本在数据库运行直接 ...
- vertx从入门到精通
1.Vert.x安装指南 http://blog.csdn.net/sdyy321/article/details/38926005 http://blog.csdn.net/chszs/articl ...
- x-shell配置远程连接
1. 打开x-shell 2. 配置编译属性 3. 配置用户的身份证信息 5. 配置完成之后选择连接
- leetcode_1048. Longest String Chain_[DP,动态规划,记忆化搜索]
1048. Longest String Chain https://leetcode.com/problems/longest-string-chain/ Let's say word1 is a ...
- Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
- ssh的server安装和安装指定版本的软件的方法
ssh程序分为有客户端程序openssh-client和服务端程序openssh-server.如果需要ssh登陆到别的电脑,需要安装openssh-client,该程序ubuntu是默认安装的.而如 ...
- Java多线程编程核心(1)
Java多线程编程核心(1) 停止线程 本节主要讨论如何更好停止一个线程.停止线程意味着在线程处理完成任务之前放弃当前操作. 1.停不了的线程 可能大多数同学会使用interrupt()来停止线程,但 ...
- js转换金钱为中文单位元、万元、亿元、万亿
function unitConvert(num) { var moneyUnits = ["元", "万元", "亿元", "万 ...
- OS复习
提纲 一 操作系统的定义,各章节名词定义. 分时多道- OS四大特征,五大功能. 二 进程 创建终止挂起激活 PCB 原语:创建终止挂起激活唤醒 互斥和同步,临界资源,临界区 信号量的基础概念,受保护 ...