【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)

题面

BZOJ

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*105,h_i,c,x<=109。

题解

很明显的克鲁斯卡尔重构树之后直接用主席树维护区间第\(K\)大。

注意克鲁斯卡尔重构树维护的最小生成树的边权是放在点上的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 200500
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
struct edge{int u,v,w;}E[MAX<<2];
bool operator<(edge a,edge b){return a.w<b.w;}
int f[MAX],tot;
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int n,m,Q,a[MAX];
int p[20][MAX],dis[MAX];
int dfn[MAX],low[MAX],ln[MAX],tim;
void dfs(int u,int ff)
{
if(u<=n)dfn[u]=low[u]=++tim,ln[tim]=u;
else dfn[u]=1e9,low[u]=0;
p[0][u]=ff;
for(int i=1;i<20;++i)p[i][u]=p[i-1][p[i-1][u]];
for(int i=h[u];i;i=e[i].next)
dfs(e[i].v,u),dfn[u]=min(dfn[u],dfn[e[i].v]),low[u]=max(low[u],low[e[i].v]);
}
int rt[MAX],S[MAX],top;
struct Node{int ls,rs,v;}t[MAX*20];
int num;
void modify(int &x,int l,int r,int p)
{
t[++num]=t[x];++t[x=num].v;if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)modify(t[x].ls,l,mid,p);
else modify(t[x].rs,mid+1,r,p);
}
int Query(int A,int B,int l,int r,int K)
{
if(l==r)return S[l];
int mid=(l+r)>>1,sum=t[t[A].rs].v-t[t[B].rs].v;
if(sum>=K)return Query(t[A].rs,t[B].rs,mid+1,r,K);
else return Query(t[A].ls,t[B].ls,l,mid,K-sum);
}
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;++i)S[i]=a[i]=read();
sort(&S[1],&S[n+1]);top=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[top+1],a[i])-S;
for(int i=1;i<=m;++i)
{
int u=read(),v=read(),w=read();
E[i]=(edge){u,v,w};
}
sort(&E[1],&E[m+1]);
for(int i=1;i<=n;++i)f[i]=i;tot=n;
for(int i=1;i<=m;++i)
{
int u=getf(E[i].u),v=getf(E[i].v);
if(u==v)continue;++tot;
f[tot]=f[u]=f[v]=tot;dis[tot]=E[i].w;
Add(tot,u);Add(tot,v);
}
dfs(tot,0);
for(int i=1;i<=n;++i)modify(rt[i]=rt[i-1],1,top,a[ln[i]]);
int lans=0;
while(Q--)
{
int v=read(),x=read(),K=read();
if(lans!=-1)v^=lans,x^=lans,K^=lans;
for(int i=19;~i;--i)
if(p[i][v]&&dis[p[i][v]]<=x)
v=p[i][v];
if(low[v]-dfn[v]+1<K)lans=-1;
else lans=Query(rt[low[v]],rt[dfn[v]-1],1,top,K);
printf("%d\n",lans);
}
return 0;
}

【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)的更多相关文章

  1. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

  2. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

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

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

  4. luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)

    题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...

  5. BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]

    BZOJ 思路 我觉得这题可持久化线段树合并也可以做 我觉得这题建出最小生成树之后动态点分治+线段树也可以做 还是学习一下Kruskal重构树吧-- Kruskal重构树,就是在做最小生成树的时候,如 ...

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

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

  7. 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

    这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...

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

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

  9. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

    题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...

  10. luogu4197 Peaks (kruskal重构树+主席树)

    按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...

随机推荐

  1. 【转】Linux系统下的ssh使用

    Linux系统下的ssh使用(依据个人经验总结)   对于linux运维工作者而言,使用ssh远程远程服务器是再熟悉不过的了!对于ssh的一些严格设置也关系到服务器的安全维护,今天在此,就本人工作中使 ...

  2. java并发之线程池的使用

    背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...

  3. jenkins的时间与服务器的时间不一致

    解决办法:

  4. [Notice]博客地址转移 vitostack.com

    个人博客地址转移至vitostack.com 这里可能不会经常更新. 欢迎访问新地址.

  5. kerkee demo编译连接过程中遇到的问题及解决方法(iOS)

    https://github.com/kercer/kerkee_ios 1.刚打开这个demo的时候是下图这个样子的,我们很自然的可以想到将kerkee.xcoderproj添加到项目里面 2.将k ...

  6. JSBridge的原理

    前言 参考来源 前人栽树,后台乘凉,本文参考了以下来源 github-WebViewJavascriptBridge JSBridge-Web与Native交互之iOS篇 Ios Android Hy ...

  7. 【Alpha】阶段第六次Scrum Meeting

    [Alpha]阶段第六次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加教师接口 增加上课信息接口 赵智源 构建后端测试点测试框架 构建后测试点测试框架 肖 ...

  8. OO学习第一阶段总结

    前言 虽然之前接触过java,也写过一些1000行左右的程序.可以说面向对象的思想和java的一些基本语法对我来说是没有难度的,但是这学期的面向对象依然给了我一个下马威.这几次的作业每次都很让我头疼. ...

  9. WebGL七点二

    与上一节相比这一节相当做了些整合和整理,目的是提高了读写效率和减少代码量,就是做了优化.这里我们只需要在顶点着色器中定义一个用于从js传递参数的变量u_MvcMatrix一看就知道是uniform变量 ...

  10. BufferedWriter与BufferedRead --------------------------Test

    package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...