题意:

  在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

分析:

  我们把题目中的限制分离出来:

  1. 困难值不超过x。

  2. 能达到的第k高的山峰。

  如果没有限制1,我们对每个连通块建线段树即可,如果没有限制2,我们我们可以选择按照kruskal的思想,按照困难值从小到大加便,离线处理询问。

  现在两个限制都在,所以我们考虑使两种算法兼容,所以我们连边时如果两个端点分别属于不同的连通块,我们就合并两个连通块,需要处理的问题是并查集合并和线段树合并。同时离线处理询问即可。

  这题还有一个加强版,是强制在线的版本,应该是一道kruskal重构树的练手题。

代码:

 #include<bits/stdc++.h>
using namespace std;
const int N=;
struct que{int a,b,c,id,ok;}a[N*];
struct seg{int ls,rs,v;}t[N*];
int n,m,q,tot=,nm1[N],nm2[N],fa[N],rt[N],ans[N*];
bool cmp(que a,que b){
return a.c==b.c?a.ok<b.ok:a.c<b.c;
} int get(int x){
return fa[x]==x?x:fa[x]=get(fa[x]);
} void update(int &x,int l,int r,int v){
if(!x) x=++tot;t[x].v=;
if(l==r) return ;int mid=l+r>>;
if(v<=mid) update(t[x].ls,l,mid,v);
else update(t[x].rs,mid+,r,v);
} int query(int x,int l,int r,int p){
if(l==r) return l;int mid=l+r>>;
if(p<=t[t[x].ls].v)
return query(t[x].ls,l,mid,p);
else return
query(t[x].rs,mid+,r,p-t[t[x].ls].v);
} int merge(int x,int y){
if(!x||!y) return x|y;
if(!t[x].ls&&!t[x].rs){
t[x].v+=t[y].v;return x;
} t[x].ls=merge(t[x].ls,t[y].ls);
t[x].rs=merge(t[x].rs,t[y].rs);
t[x].v=t[t[x].ls].v+t[t[x].rs].v;
return x;
} int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=n;i++)
scanf("%d",&nm1[i]),
nm2[i]=nm1[i],fa[i]=i;
sort(nm2+,nm2+n+);
for(int i=;i<=n;i++)
nm1[i]=lower_bound(nm2+,nm2++n,nm1[i])-nm2;
for(int i=,x,y,z;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),
a[i]=(que){x,y,z,,};
for(int i=m+,x,y,z;i<=m+q;i++)
scanf("%d%d%d",&x,&y,&z),
a[i]=(que){x,z,y,i-m,};
sort(a+,a++m+q,cmp);
for(int i=;i<=n;i++)
update(rt[i],,n,nm1[i]);
for(int i=;i<=m+q;i++)
if(!a[i].ok){
int x=get(a[i].a),y=get(a[i].b);
if(x!=y) fa[x]=y,
rt[y]=merge(rt[x],rt[y]);
} else{
int x=get(a[i].a);
if(t[rt[x]].v<a[i].b)
ans[a[i].id]=-;
else ans[a[i].id]=
nm2[query(rt[x],,n,t[rt[x]].v-a[i].b+)];
} for(int i=;i<=q;i++)
printf("%d\n",ans[i]);return ;
}

线段树合并

BZOJ3545 Peaks 离线处理+线段树合并的更多相关文章

  1. 「洛谷4197」「BZOJ3545」peak【线段树合并】

    题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...

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

    [bzoj3545][ONTAK2010]Peaks 2014年8月26日3,1512 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路 ...

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

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

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

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

  5. bzoj3545 Peaks 线段树合并

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

  6. Peaks 线段树合并

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

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

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

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

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

  9. BZOJ4552 HEOI2016/TJOI2016排序(线段树合并+线段树分裂)

    很久以前写过二分答案离线的做法,比较好理解.事实上这还是一个线段树合并+分裂的板子题,相比离线做法以更优的复杂度做了更多的事情.具体不说了.怎么交了一遍luogu上就跑第一了啊 #include< ...

随机推荐

  1. codeforces round#432 div2

    C:这道题没做出来...写了个类似极角排序的东西被卡掉了...事实上暴力就行了,因为如果在二维平面内那么最多只能有4个点,因为每个象限只能有一个点,然后这里拓展一下就是最多只能有2*k个点,k是维数, ...

  2. rake db:migrate 与 bundle exec rake db:migrate 的区别(copy)

    [说明:资料来自http://blog.csdn.net/lihuan974683978/article/details/8715414] 之前一直没弄明白rake  db:migrate 与 bun ...

  3. asp.net mvc4 新特性

    摘自:ASP.MVC Web编程 几种模板的解释

  4. CCF 201409-1 相邻数对 (水题)

    问题描述 给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1. 输入格式 输入的第一行包含一个整数n,表示给定整数的个数. 第二行包含所给定的n个整数. 输出格式 输出一个整数,表示值正好 ...

  5. SSM整合(一)

    http://www.cnblogs.com/xuerong/p/6796600.html 技术点 1.基础框架-ssm (SpringMVC +Spring +MyBatis) 2.数据库MySqQ ...

  6. 【WIP】外汇与证券交易29个技术指标

    创建: 2017/05/16   更新: 2017/05/30 更新: 2017/10/14 标题加上[WIP],增加创建时间  指标名称  函数原型(prototype)  参考与分析 (refer ...

  7. Vijos P1782 借教室 ( 前缀和&&差分序列)

    题目链接:借教室 题意:给出n天得教室数目,m个借教室得单子,按顺序借教室,问哪个单子不满足并输出 分析:可以用线段树做,会T,常数比较大,选择用差分序列维护前缀和,二分答案即可 #include&l ...

  8. bzoj 4236: JOIOJI【前缀和+map】

    设sj,so,si分别是J O I的个数前缀和,然后要求求最长(l,r)满足sj[r]-sj[l-1]==so[r]-so[l-1]==si[r]-si[l-1],化简一下就是满足so[r]-so[l ...

  9. 进击的Python【第八章】:动态导入模块、断言、socket开发之SSH,FTP

    一.动态导入模块 知道一个模块名的字符串形式,通过字符串来导入模块 mod = __import__("lib.aa") print(mod) instance = getattr ...

  10. [POI2009]救火站Gas

    Description 给你一棵树,现在要建立一些消防站,有以下要求: 1. 消防站要建立在节点上,每个节点可能建立不只一个消防站. 2. 每个节点应该被一个消防站管理,这个消防站不一定建立在该节点上 ...