BZOJ3545 Peaks 离线处理+线段树合并
题意:
在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 离线处理+线段树合并的更多相关文章
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 【bzoj3545】[ONTAK2010]Peaks 线段树合并
[bzoj3545][ONTAK2010]Peaks 2014年8月26日3,1512 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路 ...
- 【线段树合并】bzoj3545: [ONTAK2010]Peaks
1A还行 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问, ...
- [BZOJ3545] [ONTAK2010]Peaks(线段树合并 + 离散化)
传送门 由于困难值小于等于x这个很恶心,可以离线处理,将边权,和询问时的x排序. 每到一个询问的时候,将边权小于等于x的都合并起来再询问. .. 有重复元素的线段树合并的时间复杂度是nlog^2n # ...
- bzoj3545 Peaks 线段树合并
离线乱搞... 也就是一个线段树合并没什么 #include<algorithm> #include<iostream> #include<cstring> #in ...
- Peaks 线段树合并
Peaks 线段树合并 \(n\)个带权值\(h_i\)山峰,有\(m\)条山峰间双向道路,\(q\)组询问,问从\(v_i\)开始只经过\(h_i\le x\)的路径所能到达的山峰中第\(k\)高的 ...
- BZOJ.3545.[ONTAK2010]Peaks(线段树合并)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...
- 线段树合并&&启发式合并笔记
这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息. 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直 ...
- BZOJ4552 HEOI2016/TJOI2016排序(线段树合并+线段树分裂)
很久以前写过二分答案离线的做法,比较好理解.事实上这还是一个线段树合并+分裂的板子题,相比离线做法以更优的复杂度做了更多的事情.具体不说了.怎么交了一遍luogu上就跑第一了啊 #include< ...
随机推荐
- hash学习
hash真奇妙 1.子串hash:如果我们要求一段子串的hash值,设h[i]:1-i的hash值,h[l-r]=h[r]-h[l-1]*pw[r-l+1],无论是模意义下还是自然溢出都是可以的 2. ...
- bzoj 1497 [NOI2006]最大获利【最大权闭合子图+最小割】
不要被5s时限和50000点数吓倒!大胆网络流!我一个5w级别的dinic只跑了1s+! 看起来没有最大权闭合子图的特征--限制,实际上还是有的. 我们需要把中转站看成负权点,把p看成点权,把客户看成 ...
- bzoj 1625: [Usaco2007 Dec]宝石手镯【背包】
裸的01背包 #include<iostream> #include<cstdio> using namespace std; int c,n,w,v,f[20001]; in ...
- 无法生成DH密钥对Could not generate DH keypair
Source from here Add this library to classpath(following is maven project) <dependency> < ...
- B - Burning Midnight Oil CodeForces - 165B
One day a highly important task was commissioned to Vasya — writing a program in a night. The progra ...
- 洛谷 P2042 维护数列
http://blog.csdn.net/drazxlnddt/article/details/51051598 flip为true表示以当前节点为根的子树需要交换.set为true表示以当前节点为根 ...
- 状压DP+记忆化搜索 UVA 1252 Twenty Questions
题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...
- 尺取法 POJ 3320 Jessica's Reading Problem
题目传送门 /* 尺取法:先求出不同知识点的总个数tot,然后以获得知识点的个数作为界限, 更新最小值 */ #include <cstdio> #include <cmath> ...
- Activity的onSaveInstanceState和onRestoreInstanceState触发的时机
转自:http://www.cnblogs.com/heiguy/archive/2010/10/30/1865239.html 1.原文 先看Application Fundamentals上的一段 ...
- 转 ORA-00054 的解决方法
统有一个不用的索引,想删除这个索引, SQL> drop index GPSTIME_GLOBAL_INDEX 2 /drop index GPSTIME_GLOBAL_INDEX ...