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

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。

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 -- 主席树,最小生成树,倍增的更多相关文章

  1. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  2. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  3. 3551: [ONTAK2010]Peaks加强版

    3551: [ONTAK2010]Peaks加强版 https://www.lydsy.com/JudgeOnline/problem.php?id=3551 分析: kruskal重构树 +  倍增 ...

  4. BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树+dfs序

    BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道 ...

  5. [BZOJ 2989]数列(二进制分组+主席树)

    [BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...

  6. 【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)

    [BZOJ5304][HAOI2018]字串覆盖(后缀数组,主席树,倍增) 题面 BZOJ 洛谷 题解 贪心的想法是从左往右,能选就选.这个显然是正确的. 题目的数据范围很好的说明了要对于询问分开进行 ...

  7. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  8. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

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

  9. BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增

    建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...

随机推荐

  1. Vim 快捷键整理【转】

    转自:http://blog.csdn.net/ceven2010/article/details/7406341 一.移动光标 1.左移h.右移l.下移j.上移k 2.向下翻页ctrl + f,向上 ...

  2. python3 asyncio官方文档中文版

    事件循环基类 事件循环基类 事件循环是由asyncio提供的核心执行装置.它提供了多种服务,包括: 注册.执行和关闭延时调用(超时) 为各种通信创建客户端和服务端传输 为一个外部程序通信启动子进程和相 ...

  3. Html.DropDownListFor() 二级联动 ($.getJSON)

    Control: public ActionResult GetPositionName(int parentid) //发布新职位页面中的根据职位类别,获取职位名称 { List<Catego ...

  4. shell 数组基础->

    数组其实也算是变量, 传统的变量只能存储一个值, 但数组可以存储多个值. 普通数组:只能使用整数 作为数组索引 [有序 0 1 2 3 4 ]关联数组:可以使用字符串 作为数组索引 [无序 name ...

  5. 阿里云slb+https 实践操作练习

    如果只是练习按照文档步骤逐步执行即可. 如果是业务需要,只供参考. 有道笔记链接->

  6. 十一、springboot之web开发之Filter

    我们常常在项目中会使用filters用于录调用日志.排除有XSS威胁的字符.执行权限验证等等.Spring Boot自动添加了OrderedCharacterEncodingFilter和Hidden ...

  7. [HBase] 服务端RPC机制及代码梳理

    基于版本:CDH5.4.2 上述版本较老,但是目前生产上是使用这个版本,所以以此为例. 1. 概要 说明: 客户端API发送的请求将会被RPCServer的Listener线程监听到. Listene ...

  8. go语言 documentation

    Documentation文档   The Go programming language is an open source project to make programmers more pro ...

  9. 最简单删除SQL Server中所有数据的方法(不用考虑表之间的约束条件,即主表与子表的关系)

    其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSF ...

  10. switch case语句

    五.switch case语句 1.格式 Switch(表达式) { case 表达式:语句块 break: … default break: } 2.例题 输入年份.月份.日期,判断是否是闰年,并且 ...