题目传送门


分析

首先第\(k\)大一般都是主席树

问题是困难值的限制有点束手无措

又是\(\text{Kruskal重构树}\)

将困难值为边权跑最小生成树,重新建树,实际上让困难值跳到尽量大的位置就可以了,那可以倍增实现

然后找到这个点,实际可以按照dfs序代表一个区间,那么可以转换为区间求解


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011;
struct Chair{
int w[N<<5],ls[N<<5],rs[N<<5],cnt;
inline void build(int &rt,int l,int r){
w[rt=++cnt]=0; rr int mid=(l+r)>>1;
if (l<r) build(ls[rt],l,mid),build(rs[rt],mid+1,r);
}
inline void update(int &rt,int l,int r,int k){
rr int trt=++cnt,mid=(l+r)>>1;
ls[trt]=ls[rt],rs[trt]=rs[rt],w[trt]=w[rt]+1,rt=trt;
if (l==r) return;
k<=mid?update(ls[trt],l,mid,k):update(rs[trt],mid+1,r,k);
}
inline signed query(int L,int R,int l,int r,int k){
if (l==r) return l;
rr int x=w[rs[R]]-w[rs[L]],mid=(l+r)>>1;
return x<k?query(ls[L],ls[R],l,mid,k-x):query(rs[L],rs[R],mid+1,r,k);
}
}Tre;
struct node{int y,next;}e[N<<1]; struct rec{int x,y,w;}T[N*5];
int d[N<<1],ls[N<<1],fat[N<<1],f[N<<1][18],lfn[N<<1],rfn[N<<1];
int Dfn,n,k=1,m,Q,sn,dep[N<<1],rt[N],h[N],b[N],tot;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(rec x,rec y){return x.w<y.w;}
inline void add(int x,int y){e[++k]=(node){y,ls[x]},ls[x]=k;}
inline signed getf(int u){return fat[u]==u?u:fat[u]=getf(fat[u]);}
inline void Kruskal(){
for (rr int i=1;i<n*2;++i) fat[i]=i;
for (rr int i=1,tOt=0;i<=m;++i){
rr int fa=getf(T[i].x),fb=getf(T[i].y);
if (fa!=fb){
fat[fa]=fat[fb]=++sn,d[sn]=T[i].w;
add(sn,fa),add(sn,fb);
if (++tOt==n-1) return;
}
}
}
inline void dfs(int x,int fa){
f[x][0]=fa,lfn[x]=Dfn,dep[x]=dep[fa]+1;
for (rr int i=1;i<18;++i)
f[x][i]=f[f[x][i-1]][i-1];
if (!ls[x]){
lfn[x]=++Dfn;
Tre.update(rt[Dfn]=rt[Dfn-1],1,tot,h[x]);
}
for (rr int i=ls[x];i;i=e[i].next) dfs(e[i].y,x);
rfn[x]=Dfn;
}
signed main(){
Tre.cnt=0,sn=n=iut(),m=iut(),Q=iut();
for (rr int i=1;i<=n;++i) h[i]=b[i]=iut();
sort(b+1,b+1+n),tot=unique(b+1,b+1+n)-b-1;
for (rr int i=1;i<=n;++i) h[i]=lower_bound(b+1,b+1+tot,h[i])-b;
for (rr int i=1;i<=m;++i) T[i]=(rec){iut(),iut(),iut()};
sort(T+1,T+1+m,cmp),Kruskal(),Tre.build(rt[0],1,tot),dfs(sn,0);
while (Q--){
rr int x=iut(),D=iut(),Kth=iut();
for (rr int i=17;~i;--i) if (f[x][i]&&d[f[x][i]]<=D) x=f[x][i];
if (rfn[x]-lfn[x]<Kth) putchar('-'),putchar(49),putchar(10);
else print(b[Tre.query(rt[lfn[x]],rt[rfn[x]],1,tot,Kth)]),putchar(10);
}
return 0;
}

#Kruskal重构树,主席树,倍增#洛谷 4197 Peaks的更多相关文章

  1. isaster(Comet OJ - Contest #11D题+kruskal重构树+线段树+倍增)

    目录 题目链接 思路 代码 题目链接 传送门 思路 \(kruskal\)重构树\(+\)线段树\(+\)倍增 代码 #include <set> #include <map> ...

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

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

  3. 洛谷P4197 Peaks(Kruskal重构树 主席树)

    题意 题目链接 往后中文题就不翻译了qwq Sol 又是码农题..出题人这是强行把Kruskal重构树和主席树拼一块了啊.. 首先由于给出的限制条件是<=x,因此我们在最小生成树上走一定是最优的 ...

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

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

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

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

  6. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

  7. [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)

    题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...

  8. [IOI2018] werewolf 狼人 [kruskal重构树+主席树]

    题意: 当你是人形的时候你只能走 \([L,N-1]\) 的编号的点(即大于等于L的点) 当你是狼形的时候你只能走 \([1,R]\) 的编号的点(即小于等于R的点) 然后问题转化成人形和狼形能到的点 ...

  9. 【BZOJ3545】Peaks(Kruskal重构树 主席树)

    题目链接 大意 给出有\(N\)个点\(M\)条边的一张图,其中每个点都有一个High值,每条边都有一个Hard值. 再给出\(Q\)个询问:\(v\) \(x\) \(k\) 每次询问查询从点\(v ...

  10. UOJ#407. 【IOI2018】狼人 Kruskal,kruskal重构树,主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ407.html 题解 套路啊. 先按照两个节点顺序各搞一个kruskal重构树,然后问题转化成两棵krus ...

随机推荐

  1. Java Reactive Programming

    Java Reactive Programming 响应式编程 在 Spring Boot 中,支持了响应式编程,带来了性能和内存使用方面的优化. 详见: Spring: Blocking vs no ...

  2. 【Azure 应用服务】如何为Web Jobs 安装Python包呢?

    问题描述 WebJobs 怎么安装Python包? 问题解答 第一步:登录到App Service的高级管理工具(Kudu:https://<webappname>.scm.chinacl ...

  3. STM32FATFS文件系统移植

    STM32FATFS文件系统移植 1. FATFS简介 FATFS文件系统是一个用于在微控制器上运行的开源文件系统,支持FAT/FATFS.NTFS.exFAT等主流文件系统,且一直保持更新.在此以F ...

  4. 【小程序分包】小程序包大于2M,来这教你分包啊

    前言 缘由 该大的不大,小程序包超出2M,无法上传发布 前段时间项目迭代时,因版本大升级,导致uniapp打包后小程序后,包体积大于2M.虽然将图片等静态资源压缩,体积大的资源放置cdn,在不懈的努力 ...

  5. WPF入门教程系列目录

    WPF入门教程系列一--基础 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门 ...

  6. Python中的join()函数的用法实例分析

    一.join()函数 语法:  'sep'.join(seq) 参数说明sep:分隔符.可以为空seq:要连接的元素序列.字符串.元组.字典上面的语法即:以sep作为分隔符,将seq所有的元素合并成一 ...

  7. Atom安装插件的几种方式

    界面安装 打开Atom->File->Settings->Install 输入你想要安装的插件名/Theme名 命令行安装 打开cmd命令行程序 切换到.atom/package目录 ...

  8. Mysql导出导入操作

    安装mysql客户端 # 在终端上下载mysql源 wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm ...

  9. JavaFx 模拟键盘和鼠标事件

    模拟键盘事件 可实现按键的模拟,包含快捷键 模拟按下ctrl+v示例代码: val robot = Robot() robot.keyPress(KeyEvent.VK_CONTROL) robot. ...

  10. C++ bind函数

    bind()是一个函数适配器,返回一个可调用对象,他可以将一个函数的参数列表做魔改. 设置默认参数 using namespace std::placeholders; void f(int a, i ...