BZOJ 3545 / 洛谷 P4197 Peaks 解题报告
P4197 Peaks
题目描述
在\(\text{Bytemountains}\)有\(N\)座山峰,每座山峰有他的高度\(h_i\)。有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个困难值,这个值越大表示越难走,现在有\(Q\)组询问,每组询问询问从点\(v\)开始只经过困难值小于等于\(x\)的路径所能到达的山峰中第\(k\)高的山峰,如果无解输出\(-1\)。
输入输出格式
输入格式:
第一行三个数\(N\),\(M\),\(Q\)。 第二行\(N\)个数,第\(i\)个数为\(h_i\)接下来\(M\)行,每行\(3\)个数\(a,b,c\),表示从\(a\)到\(b\)有一条困难值为\(c\)的双向路径。 接下来\(Q\)行,每行三个数\(v,x,k\),一组询问。
输出格式:
对于每组询问,输出一个整数表示答案。
说明
数据范围
\(N \le 10^5\), \(0 \le M,Q \le 5\times 10^5\),\(h_i,c,x \le 10^9\) 。
恩,顺手学了一下重构树
觉得这篇洛谷日报讲的不错
说一下感受。
还是有点码量的,不太好调,写的时候认真一点,注意空间。
Code:
#include <cstdio>
#include <algorithm>
const int N=1e5+10;
const int M=5e5+10;
int n,m,q,F[N<<1],dfn[N<<1],low[N<<1],dfs_clock,ha[N<<1],f[N<<1][19],poi[N<<1];
int th[N],h[N];
struct node
{
int u,v,w;
bool friend operator <(node n1,node n2){return n1.w<n2.w;}
}e[M];
int Find(int x){return F[x]=F[x]==x?x:Find(F[x]);}
int Next[N<<1],to[N<<1],head[N<<1],cnt;
void add(int u,int v){to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;}
void dfs(int now)
{
for(int i=1;f[now][i-1];i++) f[now][i]=f[f[now][i-1]][i-1];
dfn[now]=++dfs_clock,ha[dfs_clock]=now;
for(int i=head[now];i;i=Next[i])
dfs(to[i]);
low[now]=dfs_clock;
}
int sum[N*30],ch[N*30][2],root[N<<1],tot;
#define ls ch[now][0]
#define rs ch[now][1]
#define ols ch[las][0]
#define ors ch[las][1]
int rebuild(int las,int l,int r,int pos)
{
int now=++tot,mid=l+r>>1;
if(l==r) return sum[now]=sum[las]+1,now;
if(pos<=mid)
{
ls=rebuild(ols,l,mid,pos);
rs=ors;
}
else
{
ls=ols;
rs=rebuild(ors,mid+1,r,pos);
}
return sum[now]=sum[ls]+sum[rs],now;
}
int query(int now,int las,int l,int r,int k)
{
if(k>sum[now]-sum[las]) return 0;
if(l==r) return l;
int mid=l+r>>1;
if(sum[rs]-sum[ors]>=k)
return query(rs,ors,mid+1,r,k);
else
return query(ls,ols,l,mid,k-sum[rs]+sum[ors]);
}
int find(int v,int x)//v不大于x的点
{
for(int i=18;~i;i--)
if(poi[f[v][i]]<=x)
v=f[v][i];
return v;
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
int n_=n;
for(int i=1;i<=n;i++) scanf("%d",h+i),th[i]=h[i];
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
std::sort(e+1,e+1+m);
std::sort(th+1,th+1+n);
int m_=std::unique(th+1,th+1+n)-th-1;
for(int i=1;i<=n;i++) h[i]=std::lower_bound(th+1,th+1+m_,h[i])-th;
th[0]=-1,poi[0]=0x7fffffff;
for(int i=1;i<=n*2;i++) F[i]=i;
for(int i=1;i<=m;i++)
{
int u=e[i].u,v=e[i].v,w=e[i].w;
int rt1=Find(u),rt2=Find(v);
if(rt1==rt2) continue;
F[rt1]=F[rt2]=f[rt1][0]=f[rt2][0]=++n;
add(n,rt1),add(n,rt2);
poi[n]=w;
}
dfs(n);
for(int i=1;i<=dfs_clock;i++)
{
if(ha[i]<=n_)
root[i]=rebuild(root[i-1],1,m_,h[ha[i]]);
else
root[i]=root[i-1];
}
for(int anc,v,x,k,i=1;i<=q;i++)
{
scanf("%d%d%d",&v,&x,&k);
anc=find(v,x);
printf("%d\n",th[query(root[low[anc]],root[dfn[anc]-1],1,m_,k)]);
}
return 0;
}
2018.10.16
BZOJ 3545 / 洛谷 P4197 Peaks 解题报告的更多相关文章
- 洛谷 P2058 海港 解题报告
P2058 海港 题目描述 小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客. 小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况: ...
- 洛谷 P3956 棋盘 解题报告
P3956 棋盘 题目描述 有一个\(m×m\)的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能 ...
- 洛谷 P1979 华容道 解题报告
P1979 华容道 题目描述 小\(B\)最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时 ...
- 虔诚的墓主人(BZOJ1227)(洛谷P2154)解题报告
题目描述 小W是一片新造公墓的管理人.公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地. 当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地. ...
- 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)
传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...
- [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)
题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...
- 洛谷 P2672 推销员 解题报告
P2672 推销员 题目描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第i家住户到入口的距离为 ...
- 洛谷 P2679 子串 解题报告
P2679 子串 题目描述 有两个仅包含小写英文字母的字符串\(A\)和\(B\). 现在要从字符串\(A\)中取出\(k\)个互不重叠的非空子串,然后把这\(k\)个子串按照其在字符串\(A\)中出 ...
- 洛谷 P1076 寻宝 解题报告
P1076 寻宝 题目描述 传说很遥远的藏宝楼顶层藏着诱人的宝藏.小明历尽千辛万苦终于找到传说中的这个藏宝楼,藏宝楼的门口竖着一个木板,上面写有几个大字:寻宝说明书.说明书的内容如下: 藏宝楼共有\( ...
随机推荐
- 第五课:PHP echo和print 语句
PHP echo 和 print 语句 PHP 是通过 print 和 echo 语句来动态输出 HTML 内容,虽然 print 和 echo 语句两者的功能几乎是完全一样,但是还是有一点差别的. ...
- CRC校验8
什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...
- 如何导入XML数据 (python3.6.6区别于python2 环境)
1.在python2中 代码如下图: 放在python3 环境下执行,将出现如下错误: 原因: python2中形如myTree.keys()[0]这样的写法是没有问题的,因为myTree.keys( ...
- STM32F4使用FPU+DSP库进行FFT运算的测试过程二
原文地址:http://www.cnblogs.com/NickQ/p/8541156.html 测试环境:单片机:STM32F407ZGT6 IDE:Keil5.20.0.0 固件库版本:STM32 ...
- linux文件操作篇 (四) 目录操作
#include <sys/stat.h>#include <unistd.h>#include <dirent.h> //创建文件夹 路径 掩码 int mkdi ...
- (数据科学学习手札09)系统聚类算法Python与R的比较
上一篇笔者以自己编写代码的方式实现了重心法下的系统聚类(又称层次聚类)算法,通过与Scipy和R中各自自带的系统聚类方法进行比较,显然这些权威的快捷方法更为高效,那么本篇就系统地介绍一下Python与 ...
- struts2学习笔记一
一.框架概述 1.框架的意义与作用: 所谓框架,就是把一些繁琐的重复性代码封装起来,使程序员在编码中把更多的经历放到业务需求的分析和理解上面. 特点:封装了很多细节,程序员在使用的时候会非常简单. 2 ...
- 按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示: 学生ID,,数据库,企业管理,英语,有效课程数,有效平均分
SELECT S# as 学生ID ,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='004') AS 数据库 ,(SELECT score FROM S ...
- python2.7入门---file(文件)&OS 文件&目录方法
首先file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读写操作. 2 file.f ...
- mysql学习第四天(高级查询)
-- 第七章-- 1.查询入职日期最早和最晚的日期select min(hiredate),max(hiredate)from emp -- 2.查询职位以SALES开头的所有员工平均工资,最低工资, ...