欢迎访问~原文出处——博客园-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序的更多相关文章

  1. BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3545 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

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

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

  3. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

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

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

  5. 【BZOJ3545&BZOJ3551】Peaks(kruskal重构树,主席树,dfs序)

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

  6. Codeforces 571D - Campus(并查集+线段树+DFS 序,hot tea)

    Codeforces 题目传送门 & 洛谷题目传送门 看到集合的合并,可以本能地想到并查集. 不过这题的操作与传统意义上的并查集不太一样,传统意义上的并查集一般是用来判断连通性的,而此题还需支 ...

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

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

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

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

  9. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

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

随机推荐

  1. 二、主目录 Makefile 分析(1)

    2.1 uboot 版本号 uboot 的版本号分三个级别: VERSION:主版本号 PATCHLEVEL:次版本号,为补丁级别 SUBLEVEL:再次版本号 EXTRAVERSION:附加版本信息 ...

  2. centos7之系统优化方案

    优化条目: 修改ip地址.网关.主机名.DNS等 关闭selinux,清空iptables 添加普通用户并进行sudo授权管理 更新yum源及必要软件安装 定时自动更新服务器时间 精简开机自启动服务 ...

  3. C语言练手游戏-控制台输出一个会移动的坦克

    把C语言的知识融合起来做一个练手的小游戏项目,将自己掌握到的数据结构.数组.函数.宏定义等知识综合利用,增加对语法的熟练程度. 操作系统: windows 10 x64 编译IDE : VS2015 ...

  4. 在imagenet预训模型上进行finetune

    所谓fine tune就是用别人训练好的模型,加上我们自己的数据,来训练新的模型.fine tune相当于使用别人的模型的前几层,来提取浅层特征,然后在最后再落入我们自己的分类中. fine tune ...

  5. log4j2使用入门(二)——与不同日志框架的适配

    在之前博客中已经指出log4j2可以与不同的日志框架进行适配,这里举一些实际应用进行说明: 1.比如我们在项目中使用了log4j2作为日志器,使用了log4j-api2.6.2.jar和log4j-c ...

  6. genstr.py

    #!/usr/bin/python #-*- coding:utf-8 –*- import os import sys import re import shutil import xlrd imp ...

  7. SVN设置必须锁定

    SVN是一个开放源代码的版本控制系统,相信做开发的基本上都用过,这里就不多介绍了.团队协作开发时常常会出现提交的文档互相冲突的问题,这里给大家介绍一下给SVN文件设置必须锁定的方法,当然你也可以对冲突 ...

  8. 使用ajax上传表单(带文件)

    在使用form表单的时候上传文件+表单,会使得页面跳转,而在某些时候不希望跳转,只变化页面中的局部信息 通过查找资料,可以使用FormData进行ajax操作. FormData介绍:XMLHttpR ...

  9. java 语言的主要特点

    java 语言主要特点如下: 1:简单 2:面向对象 3:分布性 4:可移植性 5:安全性 6:健壮性 二:java 主要术语 三:java 核心是面向对象程序设计OOP 四:封装 五:多态 六:继承 ...

  10. css3图片旋转

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...