题目:

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

题解:

这道题貌似是Kruskal重构树的板子题.

很长时间以前做了加强版,现在才发现还有未加强版.

赶紧把代码粘了过来水了过去.

(还记得写这份代码的时候被卡内存,用了po姐的主席树模板才过去的)

#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 200200;
const int inf = 0x3f3f3f3f;
struct Edge{
int to,next;
}G[maxn];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
struct edge{
int u,v,d;
bool friend operator < (const edge &a,const edge &b){
return a.d < b.d;
}
}zs[500500];
int n,w[maxn],ufa[maxn],m,q;
int fa[maxn][20],dis[maxn][20];
int find(int u){
return ufa[u] == u ? u : ufa[u] = find(ufa[u]);
}
void Kruskal(){
sort(zs+1,zs+m+1);
int nc = 0;
for(int i=1;i<=m;++i){
int x = find(zs[i].u);
int y = find(zs[i].v);
if(x != y){
ufa[x] = ufa[y] = ++n;
ufa[n] = n;
fa[x][0] = n;fa[y][0] = n;
dis[x][0] = dis[y][0] = zs[i].d;
add(n,x);add(n,y);
if(++nc == n-1) break;
}
}
}
int dfn[maxn],ind[maxn],oud[maxn];
int dfs_clock;
#define v G[i].to
void dfs(int u){
ind[u] = ++dfs_clock;
dfn[ind[u]] = w[u];
for(int i = head[u];i;i=G[i].next){
dfs(v);
}
oud[u] = dfs_clock;
}
#undef v
struct Node{
Node *ls,*rs;
int num;
void* operator new (size_t size,Node *_,Node *__,int ___);
}*tree[maxn],*mempool,*C,*null;
void* Node :: operator new (size_t size,Node *_,Node *__,int ___){
if(C==mempool){
C=new Node[1<<15];
mempool=C+(1<<15);
}
C->ls=_;
C->rs=__;
C->num=___;
return C++;
}
Node* build(Node *p,int x,int y,int val){
int mid=x+y>>1;
if(x==y) return new (null,null,p->num+1) Node;
if(val<=mid) return new (build(p->ls,x,mid,val),p->rs,p->num+1) Node;
else return new (p->ls,build(p->rs,mid+1,y,val),p->num+1) Node;
}
int Kth(Node *p1,Node *p2,int x,int y,int k){
int l = x,r = y;
while(l != r){
int x = p2->rs->num-p1->rs->num;
int mid = l+r >> 1;
if(k <= x){
p1 = p1->rs;p2 = p2->rs;
l = mid+1;
}else{
p1 = p1->ls;p2 = p2->ls;
r = mid;k -= x;
}
}return l;
}
int get_rt(int x,int y){
for(int j=19;~j;--j){
if(fa[x][j] && dis[x][j] <= y){
x = fa[x][j];
}
}
return x;
}
int main(){
read(n);read(m);read(q);
for(int i=1;i<=n;++i){
read(w[i]);ufa[i] = i;
}
for(int i=1;i<=m;++i){
read(zs[i].u);read(zs[i].v);
read(zs[i].d);
}
Kruskal();
for(int j = 1;j<= 19;++j){
for(int i=1;i<=n;++i){
fa[i][j] = fa[fa[i][j-1]][j-1];
dis[i][j] = cat_max(dis[i][j-1],dis[fa[i][j-1]][j-1]);
}
}
dfs(n);
null=new (0x0,0x0,0) Node;
null->ls=null->rs=null;
tree[0] = null;
for(int i=1;i<=n;++i){
tree[i] = build(tree[i-1],0,1000000000,dfn[i]);
}
int u,v,k,ans = 0;
while(q--){
read(u);read(v);read(k); int x = get_rt(u,v);
if(oud[x] - ind[x] + 1 < k){
puts("-1");
ans = 0;
continue;
}
ans = Kth(tree[ind[x]-1],tree[oud[x]],0,1000000000,k);
if(ans == 0){
puts("-1");
continue;
}
printf("%d\n",ans);
}
getchar();getchar();
return 0;
}

bzoj 3545: [ONTAK2010]Peaks Kruskal重构树的更多相关文章

  1. [ONTAK2010]Peaks kruskal重构树,主席树

    [ONTAK2010]Peaks kruskal重构树练手题. LG传送门竟然不强制在线?看到离线水过很不爽:B站强制在线版传送门 看到"询问从点\(v\)开始只经过困难值小于等于\(x\) ...

  2. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

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

  3. 【BZOJ 3732】 Network Kruskal重构树+倍增LCA

    Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...

  4. BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )

    这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是 ...

  5. BZOJ 3545: [ONTAK2010]Peaks [Splay启发式合并]

    3545: [ONTAK2010]Peaks 题意:带权图,多组询问与一个点通过边权\(\le x\)的边连通的点中点权k大值 又读错题了,输出点一直WA,问的是点权啊 本题加强版强制在线了,那这道题 ...

  6. BZOJ 4242: 水壶(Kruskal重构树 + Bfs)

    题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...

  7. luogu4197 Peaks (kruskal重构树+主席树)

    按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...

  8. 洛谷P4197 Peaks(Kruskal重构树 主席树)

    题意 题目链接 往后中文题就不翻译了qwq Sol 又是码农题..出题人这是强行把Kruskal重构树和主席树拼一块了啊.. 首先由于给出的限制条件是<=x,因此我们在最小生成树上走一定是最优的 ...

  9. BZOJ 5415: [Noi2018]归程(kruskal重构树)

    解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...

随机推荐

  1. phpcms的基础知识和配置

    一.设置界面 1.站点设置:相当于服务器上的站点 (1)站点修改:“关键词”和“描述”的修改,便于网络优化和搜索引擎对本网站的搜索. (2)点击站点后边的修改,模板的修改,引用自己模板 2.基本设置: ...

  2. 【BZOJ4358】permu kd-tree

    [BZOJ4358]permu Description 给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问.每次询问某个区间[l,r]中,最长的值域连续段长度. Input 第一行两个整 ...

  3. 记录-springMVC访问web-inf下文件问题+在jsp页面导入jquery插件路径不对问题

    环境:spring + springMvc + mybatis + maven 关于在springMVC环境访问web-inf目录下文件,其一有在springMVC xml文件下加 <!-- 对 ...

  4. C# 6.0 (C# vNext) 新功能之:Null-Conditional Operator(转)

    Null-Conditional Operator 也叫 Null propagating operator 也叫 Safe Navigation Operator 看名字,应该就有点概念了.如果还不 ...

  5. 注册会计师带你用Python进行探索性风险分析(一)

    https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/78519378

  6. python的协程和_IO操作

    协程Coroutine: 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点 ...

  7. Inside a super fast CSS engine: Quantum CSS (aka Stylo)

    https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/?utm_source=d ...

  8. mysql 分页测试,

    大环境:MySQL5.6 自己造了 27万数据, 一次性 查出来,会超时: 而分页跑,会查出来8s: 但是在少于27万时,直接查比 分页查快5倍:

  9. win7旗舰版 安装IIS中出现的问题

    最好先安装IIS成功了,再安装VS2010或者别的版本 1.hppt 错误500.19,-Internal server erroe,无法访问的请求野蛮,因为该页的相关配置数据无效,HTTP Erro ...

  10. python基础5 ---python文件处理

    python文件处理 一.文件处理的流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 二.文件的操作方法 1.文件打开模式格式: 文件句柄 = open('文件路径', ...