bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增
3545: [ONTAK2010]Peaks
Time Limit: 10 Sec Memory Limit: 128 MB
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。
Source
首先一定是走最小生成树上的边是最优的,然后我们按建树的顺序合并节点,这样我们发现一个子树里的边权都小于他本身
然后查询就是倍增找到当前点能到的最远的祖先,就变成了查询子树的第k大,然后用主席树维护就可以了
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 1000000007
#define ll long long
#define M 6000010
#define N 500010
inline int rd()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,Q;
int h[N];
struct qaz{int a,b,c;}e[N],tp[N];
bool cmp(qaz a,qaz b){return a.c<b.c;}
int fa[N],mz;
int findf(int x){return x==fa[x]?x:fa[x]=findf(fa[x]);}
int lj[N],fro[N],to[N],cnt;
void add(int a,int b){fro[++cnt]=lj[a];to[cnt]=b;lj[a]=cnt;}
bool vs[N];
int st[N],ed[N],tim,dep[N];
int Fa[][],rt[N];
int ls[M],rs[M],sz[M],tot;
void add(int lst,int &p,int l,int r,int x)
{
p=++tot;
ls[p]=ls[lst];rs[p]=rs[lst];
sz[p]=sz[lst]+;
if(l==r) return;
int mid=l+r>>;
if(x<=mid) add(ls[lst],ls[p],l,mid,x);
else add(rs[lst],rs[p],mid+,r,x);
}
void dfs(int x)
{
st[x]=++tim;vs[x]=;
dep[x]=dep[Fa[x][]]+;
if(x<=n) add(rt[tim-],rt[tim],,n,h[x]);
else rt[tim]=rt[tim-];
for(int i=;i<;i++)
{
if(dep[x]<(<<i)) break;
Fa[x][i]=Fa[Fa[x][i-]][i-];
}
for(int i=lj[x];i;i=fro[i])
{
Fa[to[i]][]=x;
dfs(to[i]);
}
ed[x]=tim;
}
int fd(int x,int y,int l,int r,int k)
{
if(l==r) return tp[l].c;
int mid=l+r>>;
if(sz[rs[x]]-sz[rs[y]]>=k) return fd(rs[x],rs[y],mid+,r,k);
else return fd(ls[x],ls[y],l,mid,k-sz[rs[x]]+sz[rs[y]]);
}
int main()
{
mz=n=rd();m=rd();Q=rd();
for(int i=;i<=n;i++) tp[i].c=rd(),tp[i].a=i;
sort(tp+,tp+n+,cmp);
for(int i=;i<=n;i++)
{
if(i>&&tp[i].c==tp[i-].c) h[tp[i].a]=h[tp[i-].a];
else h[tp[i].a]=i;
}
for(int i=,a,b,c;i<=m;i++)
{
a=rd();b=rd();c=rd();
e[i]=(qaz){a,b,c};
}
sort(e+,e+m+,cmp);
for(int i=;i<n+n;i++) fa[i]=i;
for(int i=,x,y;i<=m;i++)
{
x=findf(e[i].a);y=findf(e[i].b);
if(x==y) continue;
fa[x]=fa[y]=++mz;
h[mz]=e[i].c;
add(mz,x);add(mz,y);
if(mz==n*-) break;
}
for(int i=;i<=n;i++) if(!vs[i]) dfs(findf(i));
int x,y,z,lans=-,Rt;
while(Q--)
{
x=rd();y=rd();z=rd();
Rt=x;
for(int i=;i>=;i--)
if(dep[Rt]>(<<i)&&h[Fa[Rt][i]]<=y) Rt=Fa[Rt][i];
if(sz[rt[ed[Rt]]]-sz[rt[st[Rt]-]]<z) lans=-;
else lans=fd(rt[ed[Rt]],rt[st[Rt]-],,n,z);
printf("%d\n",lans);
}
return ;
}
bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增的更多相关文章
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- 3551: [ONTAK2010]Peaks加强版
3551: [ONTAK2010]Peaks加强版 https://www.lydsy.com/JudgeOnline/problem.php?id=3551 分析: kruskal重构树 + 倍增 ...
- BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树+dfs序
BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道 ...
- [BZOJ 2989]数列(二进制分组+主席树)
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...
- 【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)
[BZOJ5304][HAOI2018]字串覆盖(后缀数组,主席树,倍增) 题面 BZOJ 洛谷 题解 贪心的想法是从左往右,能选就选.这个显然是正确的. 题目的数据范围很好的说明了要对于询问分开进行 ...
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...
随机推荐
- springCloud全实战超详细代码demo+笔记
码云: https://gitee.com/houzheng1216/springcloud
- mysql中使用日期加减时无法识别年-月格式数据的问题,%Y-%m"这种格式数据
最新做报表统计的时候处理按月统计部分时发现,虽然使用 DATE_FORMAT( time, '%Y-%m' ) 函数可以将日期格式转成年-月,但是如果是参数是年-月格式,即"2018-10& ...
- Small Private Cloud Deployment Solution
项目背景 为用户提供可访问的桌面虚拟机,方便软件研发人员日常办公,软件开发,编译等工作.主要操作包括Visor制图.程序开发测试以及使用office软件办公. 目前阶段需要支持100台虚拟机(4VCP ...
- Python的日志记录-logging模块的使用
一.日志 1.1什么是日志 日志是跟踪软件运行时所发生的事件的一种方法,软件开发者在代码中调用日志函数,表明发生了特定的事件,事件由描述性消息描述,同时还包含事件的重要性,重要性也称为级别或严重性. ...
- ActiveMQ 使用场景
ActiveMQ 安装测试就不做介绍了,下面我说说ActiveMQ 使用场景.(松耦合与ActiveMQ) 1.非均匀应用集成 ActiveMQ 中间件用Java语言编写,因此自然提供Java客户端 ...
- js实现ctrl+v粘贴图片或是截图
浏览器环境:谷歌浏览器 1.ctrl+v粘贴图片都是监听paste时间实现的,复制的数据都存在clipboardData下面,虽然打印显示数据长度为0,但是还是可以获取数据的 2.打印clipboar ...
- 深度学习在美团点评推荐平台排序中的应用&& wide&&deep推荐系统模型--学习笔记
写在前面:据说下周就要xxxxxxxx, 吓得本宝宝赶紧找些广告的东西看看 gbdt+lr的模型之前是知道怎么搞的,dnn+lr的模型也是知道的,但是都没有试验过 深度学习在美团点评推荐平台排序中的运 ...
- P2471 [SCOI2007]降雨量
Description 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2 ...
- MySQL学习笔记:计算机服务中找不到MySQL服务
不知道什么原因,连接了远程服务器之后,本地服务就连接不上. 经排查,发现服务中的MySQL服务居然不见,一番搜索之后,在CMD中进入到MySQL安装目录的bin下执行以下语句: mysqld.exe ...
- Nginx 虚拟主机 VirtualHost 配置
Nginx 是一个轻量级高性能的 Web 服务器, 并发处理能力强, 对资源消耗小, 无论是静态服务器还是小网站, Nginx 表现更加出色, 作为 Apache 的补充和替代使用率越来越高. 我在& ...