题目描述

在Bytemountains有N座山峰,每座山峰有他的高度\(h_i\)。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

输入输出格式

输入格式:

第一行三个数N,M,Q。 第二行N个数,第ii个数为\(h_i\) 接下来MM行,每行33个数a,b,c,表示从a到b有一条困难值为c的双向路径。 接下来Q行,每行三个数v,x,k,表示一组询问。

输出格式:

对于每组询问,输出一个整数表示答案。

输入输出样例

输入样例#1: 复制

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

输出样例#1: 复制

6
1
-1
8

说明

数据范围

\(N \le 10^5, 0 \le M,Q \le 5\times 10^5,h_i,c,x \le 10^9\)。


kruskal重构树
对于每一个节点其子树的叶子就是在这个点的权值内能相互到达的点
按照dfs序建可持久化权值线段树,dfs序\(u\)到\(u+size[u]\)内每个点的增量就是\(pre[u]\)子树的点
每次查询时把\(v\)倍增跳到\(\leq x\)的最大值,在\((dfn[x]+size[x])-(dfn[x]-1)\)的线段树内找第\(k\)大节点即可


恩......


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define M (200005*10)
#define N 200005
#define LL long long
#define max(a,b) ((a)>(b)? (a):(b))
#define min(a,b) ((a)<(b)? (a):(b))using namespace std;int top[N],d[M],h[N],ls[M],rs[M],n,m,q,cnt,f[N],edge[N],cnt1,y;
int head[N],ver[N],nex[N],dfn[N],df,pre[M],g,z[N],pp[N],v,x,k,bz[N][26],s[N],az[N][26];
struct vv{  int f,t,edge;} a[M];
inline bool cmp(vv a,vv b) {return a.edge<b.edge;}inline char gc()
{static char now[1<<22],*S,*T;if (T==S){T=(S=now)+fread(now,1,1<<22,stdin);if (T==S) return EOF;}return *S++;
}
inline int gtt()
{register int x=0,f=1;register char ch=gc();while(!isdigit(ch)){if (ch=='-') f=-1;ch=gc();}while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=gc();return x*f;
}
inline void add(int x,int y)
{cnt1+=1;ver[cnt1]=y; nex[cnt1]=head[x]; head[x]=cnt1;
}int ff(int x)
{if(f[x]==x) return x;f[x]=ff(f[x]);return f[x];
}inline void kru()
{for(int i=1;i<=m;i++){int w=ff(a[i].f), e=ff(a[i].t);if(w!=e){f[w]=f[e]=++n;add(n,w); add(n,e);edge[n]=a[i].edge;}}
}void dfs(int now)
{bz[now][0]=edge[now]; s[now]=1; dfn[now]=++df; pre[df]=now;for(int i=head[now];i;i=nex[i]){int t=ver[i];dfs(t);bz[t][1]=edge[now];az[t][1]=now;s[now]+=s[t];}
}void built(int now,int l,int r,int pre,int z)
{if(l==r){d[now]=d[pre]+1;return;}int mid=(l+r)>>1; ls[now]=ls[pre]; rs[now]=rs[pre];if(z<=mid){ls[now]=++cnt;built(ls[now],l,mid,ls[pre],z);}if(z>mid){rs[now]=++cnt;built(rs[now], mid+1, r, rs[pre], z);}d[now]=d[ls[now]]+d[rs[now]];
}void built1(int now,int l,int r)
{if(l==r) return;ls[now]=++cnt; rs[now]=++cnt;int mid=(l+r)>>1;built1(ls[now], l, mid);built1(rs[now], mid+1, r);
}int find(int now1,int now2,int l,int r,int z)
{if(l==r) return l; if(d[now2]-d[now1]<z) return -1;int mid=(l+r)>>1;if(d[rs[now2]]-d[rs[now1]]>=z) return find(rs[now1], rs[now2], mid+1, r, z);return find(ls[now1], ls[now2], l, mid, z-d[rs[now2]]+d[rs[now1]]);
}int main()
{n=gtt(); m=gtt(); q=gtt();  g=n;for(int i=1;i<=4*n;i++) f[i]=i;for(int i=1;i<=n;i++) h[i]=gtt(), z[i]=h[i];sort(z+1,z+1+n);int mm=unique(z+1,z+1+n)-z-1;for(int i=1;i<=n;i++) {k=lower_bound(z+1,z+1+mm,h[i])-z;pp[k]=h[i]; h[i]=k;}for(int i=1;i<=m;i++){ a[i].f=gtt(); a[i].t=gtt(); a[i].edge=gtt();}sort(a+1,a+1+m,cmp); kru(); for(int i=n;i;i--)  if(!dfn[i]) dfs(i);if(g!=1){top[1]=1; cnt=1; built1(1,1,mm);}else {top[1]=1; cnt=1;built(cnt,1,mm,0,h[pre[1]]);}for(int i=2;i<=n;i++) if(pre[i]<=g) {top[i]=++cnt;built(cnt,1,mm,top[i-1],h[pre[i]]);}else top[i]=top[i-1];for(int i=2;i<=25;i++) for(int j=1;j<=n;j++) bz[j][i]=bz[az[j][i-1]][i-1], az[j][i]=az[az[j][i-1]][i-1];for(int i=1;i<=q;i++){v=gtt(); x=gtt(); k=gtt();for(int j=25;j>=1;j--) if(bz[v][j]<=x && az[v][j]) v=az[v][j];k=find(top[dfn[v]-1],top[dfn[v]+s[v]-1],1,mm,k);if(k!=-1)printf("%d\n",pp[k]);else printf("-1\n");}
}

转载于:https://www.cnblogs.com/ZUTTER/p/9835735.html

P4197 Peaks相关推荐

  1. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)

    题目链接:点击查看 题目大意:有 n 座山峰,每座山峰有他的高度 h[ i ] ,有些山峰之间有双向道路相连,共 m 条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有 q 组询问,每组询问 ...

  2. kruskal重构树练习

    洛谷 P4197 Peaks 题意: 有 nnn 个山峰,每一个山峰高 hih_ihi​ ,有 mmm 条双向带权边将一些山峰连接起来,有 qqq 次询问,每次询问 (v,x,k)(v,x,k)(v, ...

  3. P4197 【Peaks】克鲁斯卡尔重构树详解

    \(\texttt{Kruskal}\) 重构树 -- 需要一定基础的简单算法 题目大意: 给你一个无向图,可能有很多个连通块 给定一些询问 \(v,x,k\),代表在 \(v\{\}\) 这个连通块 ...

  4. 密度聚类(Density peaks Clustering)Python实现

    密度聚类(Density peaks Clustering)Python实现 原文:http://blog.csdn.net/kryolith/article/details/39832573 Rod ...

  5. [MATLAB学习笔记]peaks函数1013(2)

    >> Z = peaksZ =1 至 10 列0.0001 0.0001 0.0002 0.0004 0.0007 0.0011 0.0017 0.0025 0.0034 0.00430. ...

  6. Clustering by density peaks and distance

    这次介绍的是Alex和Alessandro于2014年发表在的Science上的一篇关于聚类的文章[13],该文章的基本思想很简单,但是其聚类效果却兼具了谱聚类(Spectral Clustering ...

  7. 文献学习(part33)--Clustering by fast search and find of density peaks

    学习笔记,仅供参考,有错必究 文章目录 Clustering by fast search and find of density peaks 摘要 简介 算法 实验(略) Clustering by ...

  8. [BZOJ3545][ONTAK2010]Peaks

    [BZOJ3545][ONTAK2010]Peaks 试题描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越 ...

  9. #3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)

    #3551. [ONTAK2010]Peaks加强版 我们要求从一个点出发经过困难值小于等于xxx的路径所能到达的山峰中第kkk高的是什么. 考虑按照边权升序,建议kruskalkruskalkrus ...

最新文章

  1. android 服务器异步回调,android – 如何从异步任务返回结果
  2. 分割 bisenetv2笔记
  3. php性能分析工具XHProf安装配置使用教程(linux精华版)
  4. python运算学习之Numpy ------ 数组的切片索引与循环遍历、条件和布尔数组、形状变化...
  5. [C++11]右值和右值引用
  6. python的zip方法_python zip()函数使用方法解析
  7. 暑期训练日志----2018.8.26
  8. php orm教程,Laravel ORM 数据model操作教程
  9. mysql regexp边界_MySQL中REGEXP正则表达式使用大全
  10. 视频编解码(十三):list_for_each_entry列表总结
  11. android x86 ib,IB驱动安装
  12. STM32——直流电机控制与TB6612FNG驱动芯片
  13. 这9个技巧让你的PyTorch模型训练得飞快!
  14. 根据示波器存储的波形数据得到两列信号的相位差(MATLAB源码)
  15. 小程序请求后端接口步骤
  16. 毕业设计-基于机器学习的股票预测
  17. idea在plugins中搜不到插件MyBatisX
  18. 东京奥运会:创意可以接地气,但别接“阴气”
  19. 如何删除电脑计算机用户,mininews怎么卸载_电脑上的mininews新闻如何删除-win7之家...
  20. 为什么有些人已经那么接近成功,但是,最终却没有能够取得成功?

热门文章

  1. pythontkinter窗口外观样式_Python GUI之tkinter窗口视窗教程大集合(推荐)
  2. 2017年9月全国计算机等级考试报名时间,广东省2017年9月全国计算机等级考试报名...
  3. 【SUMO学习】初级 Hello World
  4. hive自定义函数-身份证号合法性判断
  5. SAS导入Excel数据集时报错:“ERROR: 连接: 没有注册类”
  6. 【ArcGIS】连接到数据库失败,出现基础数据库错误,没有注册类
  7. 纹波测量 以及 ATX 12V PC 电源 介绍
  8. 代码随想录算法训练营day25| 216.组合总和III、17.电话号码的字母组合
  9. 安装驱动程序(2)----安装过滤驱动
  10. Redis挂了,流量把数据库也打挂了,怎么办?