BZOJ3551 [ONTAK2010]Peaks加强版 kruskal 并查集 主席树 dfs序
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ3551
题意概括
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
对于每组询问,输出一个整数表示答案。
题解
假题。
作为蒟蒻的我不敢写题解了。
给个好链接:http://blog.csdn.net/PoPoQQQ/article/details/41348785
代码
#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;
struct Edge{
int x,y,z;
void read(){
scanf("%d%d%d",&x,&y,&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(){
scanf("%d%d%d",&n,&m,&q);
for (int i=1;i<=n;i++)
scanf("%d",&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]]);
int lastans=0;
for (int i=1;i<=q;i++){
int v,x,k,y;
scanf("%d%d%d",&v,&x,&k);
if (~lastans)
v^=lastans,x^=lastans,k^=lastans;
y=find(v,x);
if (out[y]-in[y]<k)
lastans=-1;
else
lastans=query(root[in[y]],root[out[y]],1,n,k);
printf("%d\n",lastans);
}
return 0;
}
BZOJ3551 [ONTAK2010]Peaks加强版 kruskal 并查集 主席树 dfs序的更多相关文章
- BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3545 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2438 Solved: 763[Submit][ ...
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]
BZOJ 思路 我觉得这题可持久化线段树合并也可以做 我觉得这题建出最小生成树之后动态点分治+线段树也可以做 还是学习一下Kruskal重构树吧-- Kruskal重构树,就是在做最小生成树的时候,如 ...
- 【BZOJ3545&BZOJ3551】Peaks(kruskal重构树,主席树,dfs序)
题意:在Bytemountains有N座山峰,每座山峰有他的高度h_i. 有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走, 现在有Q组询问,每组询问询问从点v开始只 ...
- Codeforces 571D - Campus(并查集+线段树+DFS 序,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 看到集合的合并,可以本能地想到并查集. 不过这题的操作与传统意义上的并查集不太一样,传统意义上的并查集一般是用来判断连通性的,而此题还需支 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树
bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...
随机推荐
- VS Sln图标空白修复办法
环境:Win10,VS2017,曾经安装并卸载过VS2015之前安装了两个版本的VisualStudio,卸载一个后,就出现了图标空白问题,重新设置默认打开程序也没有作用,经摸索解决办法如下.(1)在 ...
- This page is about building Firefox Desktop
This page is about building Firefox Desktop The Mozilla build system, like the rest of the Mozilla c ...
- 第17月第7天 iOS 数组越界,防Crash处理
1. 上面方法已经可以避免crash,为了避免冗余的代码,写一个NSArray的分类,利用runtime替换NSArray的对象方法objectAtIndex:,在这里进行判断,捕获异常: #impo ...
- SpringBoot2.x配置文件讲解
SpringBoot2.x配置文件讲解 简介:SpringBoot2.x常见的配置文件 xml.yml.properties的区别和使用 xml.properties.json.yaml 1.常见的配 ...
- 在使用kvc进行赋值的时候,有时候会遇到null值,这个时候我们使用kvc会报错
在使用kvc进行赋值的时候,有时候会遇到null值,这个时候我们使用kvc会报错,如何解决 控制器代码如下: // // ViewController.m // 02-模型中的赋值 // // Cre ...
- linux 命令格式
1.命令 选项 参数 选项——短选项: - 多个选项可以合在一起书写 ——长选项:-- 选项是一个word 参数:命令的作用对象 ls -la /etc /opt 2.su swit ...
- python3之协程
1.协程的概念 协程,又称微线程,纤程.英文名Coroutine. 线程是系统级别的它们由操作系统调度,而协程则是程序级别的由程序根据需要自己调度.在一个线程中会有很多函数,我们把这些函数称为子程序, ...
- RNN(1) ------ “理解LSTM”(转载)
原文链接:http://www.jianshu.com/p/9dc9f41f0b29 Recurrent Neural Networks 人类并不是每时每刻都从一片空白的大脑开始他们的思考.在你阅读这 ...
- linux内核中链表代码分析---list.h头文件分析(二)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...
- dubbo系列二、dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台)
一.zookeeper配置中心安装 1.下载安装包,zookeeper-3.4.6.tar.gz 2.解压安装包,修改配置文件 参考zookeeper-3.4.6/conf/zoo_sample.cf ...