BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ3545
题意概括
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
对于每组询问,输出一个整数表示答案。
题解
代码
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=100005,M=500005,S=N*2,Inf=1e9+5;
bool isd(char ch){
return '0'<=ch&&ch<='9';
}
void read(int &x){
x=0;
char ch=getchar();
while (!isd(ch))
ch=getchar();
while (isd(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
}
struct Edge{
int x,y,z;
void Read(){
read(x),read(y),read(z);
}
}e[M];
bool cmpz(Edge a,Edge b){
return a.z<b.z;
}
struct MQset{//并查集
int cnt,fa[N*2];
void clear(){cnt=0;}
int getf(int k){return fa[k]==k?k:fa[k]=getf(fa[k]);}
void push(int x){fa[x]=x;}
void merge(int x,int y){fa[getf(x)]=getf(y);}
}s;
int n,m,q,h[N];
int fa[S],lc[S],rc[S],val[S],cnt;
int anst[S][20],time,in[S],out[S],dfn[S];
void dfs(int rt){
anst[rt][0]=fa[rt];
for (int i=1;i<20;i++)
anst[rt][i]=anst[anst[rt][i-1]][i-1];
in[rt]=time;
if (!lc[rt])
dfn[++time]=rt;
else
dfs(lc[rt]),dfs(rc[rt]);
out[rt]=time;
}
const int SIZE=N*2*20*2;
int Ha[N],hs;
int ls[SIZE],rs[SIZE],sum[SIZE],total,root[N];
void LSH(){
int hs_=1;
sort(Ha+1,Ha+hs+1);
for (int i=2;i<=hs;i++)
if (Ha[i]!=Ha[i-1])
Ha[++hs_]=Ha[i];
hs=hs_;
}
int find(int x){
return lower_bound(Ha+1,Ha+hs+1,x)-Ha;
}
void build(int &rt,int L,int R){
rt=++total;
sum[rt]=0;
if (L==R)
return;
int mid=(L+R)>>1;
build(ls[rt],L,mid);
build(rs[rt],mid+1,R);
}
void add(int prt,int &rt,int L,int R,int pos){
rt=++total;
if (L==R){
sum[rt]=sum[prt]+1;
return;
}
int mid=(L+R)>>1;
if (pos<=mid)
add(ls[prt],ls[rt],L,mid,pos),rs[rt]=rs[prt];
else
add(rs[prt],rs[rt],mid+1,R,pos),ls[rt]=ls[prt];
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
}
int query(int prt,int rt,int L,int R,int k){
if (L==R)
return Ha[L];
int Rz=sum[rs[rt]]-sum[rs[prt]];
int mid=(L+R)>>1;
if (Rz>=k)
return query(rs[prt],rs[rt],mid+1,R,k);
else
return query(ls[prt],ls[rt],L,mid,k-Rz);
}
int find(int x,int v){
for (int i=19;i>=0;i--)
if (val[anst[x][i]]<=v)
x=anst[x][i];
return x;
}
int main(){
read(n),read(m),read(q);
for (int i=1;i<=n;i++)
read(h[i]),Ha[i]=h[i];
hs=n;
LSH();
for (int i=1;i<=n;i++)
h[i]=find(h[i]);
for (int i=1;i<=m;i++)
e[i].Read();
sort(e+1,e+m+1,cmpz);
s.clear();
for (int i=1;i<=n;i++){
s.push(i);
fa[i]=lc[i]=rc[i]=val[i]=0;
}
cnt=n;
for (int i=1;i<=m;i++){
int x=e[i].x,y=e[i].y,z=e[i].z;
x=s.getf(x),y=s.getf(y);
if (x==y)
continue;
s.push(++cnt);
fa[x]=fa[y]=cnt;
fa[cnt]=0,lc[cnt]=x,rc[cnt]=y,val[cnt]=z;
s.fa[x]=s.fa[y]=cnt;
}
val[0]=Inf;
time=0;
dfs(cnt);
build(root[0],1,n);
for (int i=1;i<=n;i++)
add(root[i-1],root[i],1,n,h[dfn[i]]);
for (int i=1;i<=q;i++){
int v,x,k,y;
read(v),read(x),read(k);
y=find(v,x);
if (out[y]-in[y]<k)
puts("-1");
else
printf("%d\n",query(root[in[y]],root[out[y]],1,n,k));
}
return 0;
}
BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序的更多相关文章
- BZOJ3551 [ONTAK2010]Peaks加强版 kruskal 并查集 主席树 dfs序
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3551 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...
- [ONTAK2010]Peaks kruskal重构树,主席树
[ONTAK2010]Peaks kruskal重构树练手题. LG传送门竟然不强制在线?看到离线水过很不爽:B站强制在线版传送门 看到"询问从点\(v\)开始只经过困难值小于等于\(x\) ...
- Codeforces 571D - Campus(并查集+线段树+DFS 序,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 看到集合的合并,可以本能地想到并查集. 不过这题的操作与传统意义上的并查集不太一样,传统意义上的并查集一般是用来判断连通性的,而此题还需支 ...
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序
[BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...
- BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- 洛谷P3402 【模板】可持久化并查集 [主席树,并查集]
题目传送门 可持久化并查集 n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 ...
- bzoj2733 离线+并查集+主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=2733 网上清一色的合并线段树题解,我又不会,只能自己胡来,没想到Rush过去了 永无乡包含 n 座 ...
随机推荐
- Linux TCP 连接数
查看 TCP 连接数 : 每一个 IP 访问的链接数:head 默认 前10 netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print ...
- Postfix 邮件服务 - 基础服务
环境 centos 6.5 x64 测试 IP:172.16.2.18 1.关闭selinux # cat /etc/selinux/config SELINUX=disabled 2.配置 ipta ...
- 绘图QPainter-字体
方式一: import sys from PyQt5.QtGui import QPainter, QFont,QPen from PyQt5.QtWidgets import QApplicatio ...
- JavaScript之DOM概念
一.DOM概念 1.DOM是什么? 1.1 起源.DOM起源于Netscape与Microsoft 公司的DHTML(动态HTML). 1.2 名词解释.Document Object Model,文 ...
- HDU1233 还是畅通工程【最小生成树】
题意: 求出连接各个村庄最小的公路总长度,把最小公路总长度求出来. 思路: 最小生成树原理,带入数据求得. 代码: prim: #include<iostream> #include< ...
- _vimrc(VimScript脚本语言学习)
Windows下 syntax on "高亮 "缩进 set cindent "set cin set smartindent "set si set auto ...
- 在window系统下安装Sass
1.Ruby下载 因为Sass依赖于Ruby环境,所以应先在window系统下安装Ruby,Ruby安装包下载链接:http://rubyinstaller.org/downloads/ 2.Ruby ...
- C语言文件操作详解
C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现.文件操作标准库函数有: 文件的打开操作 fopen 打开一个文件 文件的关闭操作 fclose 关闭一个文件 ...
- MySQL(二)MySQL的启动或链接失败
有时候用命令mysql -u root -p 或者服务器启动mysql数据库的时候,会出现抛出异常并失败. 以下是遇过的异常. 1.1)抛出的异常:出现ERROR 2002 (HY000): Can' ...
- 3d图像识别基础论文:pointNet阅读笔记
PointNet 论文阅读: 主要思路:输入独立的点云数据,进行变换不变性处理(T-net)后,通过pointNet网络训练后,最后通过最大池化和softMax分类器,输出评分结果. 摘要: 相较于之 ...