【bzoj3545】[ONTAK2010]Peaks

2014年8月26日3,1512

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

10 11 4
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

6
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 线段树合并的更多相关文章

  1. BZOJ.3545.[ONTAK2010]Peaks(线段树合并)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...

  2. Peaks 线段树合并

    Peaks 线段树合并 \(n\)个带权值\(h_i\)山峰,有\(m\)条山峰间双向道路,\(q\)组询问,问从\(v_i\)开始只经过\(h_i\le x\)的路径所能到达的山峰中第\(k\)高的 ...

  3. bzoj3545 Peaks 线段树合并

    离线乱搞... 也就是一个线段树合并没什么 #include<algorithm> #include<iostream> #include<cstring> #in ...

  4. 【线段树合并】bzoj3545: [ONTAK2010]Peaks

    1A还行 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问, ...

  5. [BZOJ3545] [ONTAK2010]Peaks(线段树合并 + 离散化)

    传送门 由于困难值小于等于x这个很恶心,可以离线处理,将边权,和询问时的x排序. 每到一个询问的时候,将边权小于等于x的都合并起来再询问. .. 有重复元素的线段树合并的时间复杂度是nlog^2n # ...

  6. BZOJ3545 Peaks 离线处理+线段树合并

    题意: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...

  7. bzoj3545: [ONTAK2010]Peaks 重构树 主席树

    题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...

  8. 线段树合并&&启发式合并笔记

    这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息. 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直 ...

  9. bzoj3545 [ONTAK2010]Peaks、bzoj3551 [ONTAK2010]Peaks加强版

    题目描述: bzoj3545,luogu bzoj3551 题解: 重构树+线段树合并. 可以算是板子了吧. 代码(非强制在线): #include<cstdio> #include< ...

随机推荐

  1. _T(x) _TEXT(x) L 代表什么?

    首先  <tchar.h>中 #ifdef  _UNICODE .... #define __T(x)      L ## x  //替换 #else   /* ndef _UNICODE ...

  2. Itunes共享机制实现

    http://www.raywenderlich.com/1948/itunes-tutorial-for-ios-how-to-integrate-itunes-file-sharing-with- ...

  3. NSCopying协议和copy方法

    不是所有的对象都支持 copy需要继承NSCopying 协议(实现 copyWithZone: 方法)同样,需要继承NSMutableCopying 协议才可以使用mutableCopy(实现 mu ...

  4. C#编写高并发数据库控制

    往往大数据量,高并发时, 瓶颈都在数据库上, 好多人都说用数据库的复制,发布, 读写分离等技术, 但主从数据库之间同步时间有延迟.代码的作用在于保证在上端缓存服务失效(一般来说概率比较低)时,形成倒瓶 ...

  5. Workrave怎么用 Workrave使用方法, Workrave 健康计时器,预防电脑长期操作的职业病伤害

    下载绿色版: https://portableapps.com/apps/utilities/workrave_portable 选择阅读模式: 中文: 可以只选择启动休息的计时器,这样其他2个就不用 ...

  6. C# 使用Epplus导出Excel [1]:导出固定列数据

    C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...

  7. 【dp】数字游戏&寒假祭

    区间DP 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按 ...

  8. dubbo---------timeout与retires

    相信很多人都见过这张图,这张图说明了提供者与消费者之间的关系,下面就介绍一下这个图是什么意思. 1.角色解释: Provider: 暴露服务的服务提供者. Consumer: 调用远程服务的服务消费者 ...

  9. (16)zabbix history trends历史与趋势数据详解

    1. 保留历史数据 我们可以通过如下方式来设置保留数据的时长:监控项(item)配置里匹配更新监控项(item)设置Housekeeper tasksHousekeeper会定期删除过期的数据.如果数 ...

  10. GIMP工具箱的自定义操作

    首选项 中还包含工具箱的自定义操作: