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$ 大的问 ...
随机推荐
- connect by和strart with子句
--使用connect by和strart with子句 SELECT [level],column,expression, ... FROM table [WHERE where_clause] [ ...
- 60、二叉搜索树的第k个结点
一.题目 给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4. 二.解法 package algorithm ...
- maven profile 优先级
maven profile是有优先级别 也就是说在setting.xml的profile优先级比pom中同名的profile高. 可以使用 mvn help:active-profiles 这个命令是 ...
- 数据库--mysql介绍
一:什么是数据库 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文件 ...
- Jmeter 接口测试-请求 Headers 与传参方式
1.添加信息表头. 注意:1.使用Parameters时,Content-Type要么不传,要么传application/x-www-form-urlencoded,因为不传时默认值就是applica ...
- CentOS/Linux 网卡设置 IP地址配置
CentOS/Linux下设置IP地址 1:临时修改:1.1:修改IP地址# ifconfig eth0 192.168.100.100 1.2:修改网关地址# route add default g ...
- 多路复用IO与NIO
最近在学习NIO相关知识,发现需要掌握的知识点非常多,当做笔记记录就下. 在学NIO之前得先去了解IO模型 (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(No ...
- (二) solr 索引数据导入:xml格式
xml 是最常用的数据索引格式,不仅可以索引数据,还可以对文档与字段进行增强,从而改变它们的重要程度. 下面就是具体的实现方式: schema.xml的字段配置部分如下: <field name ...
- CodeIgniter典型的表单提交验证代码
view内容: <?php echo form_open('user/reg'); ?> <h5>用户名</h5> <input type="tex ...
- java8 - 多线程时间安全问题
import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeForma ...