题目:

在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. Django模板系统(非常详细)(后台数据如何展示在前台)

    前面的章节我们看到如何在视图中返回HTML,但是HTML是硬编码在Python代码中的这会导致几个问题:1,显然,任何页面的改动会牵扯到Python代码的改动网站的设计改动会比Python代码改动更频 ...

  2. Unity框架入门

    介绍Unity框架之前,先要说几个概念DIP依赖倒置原则.IOC控制反转.DI依赖注入 DIP是设计原则之一,定义:上层不应该依赖于底层,两者都依赖于抽象: 抽象不依赖于细节,细节应该依赖于抽象. 像 ...

  3. 2218 补丁vs错误

    2218 补丁vs错误 1999年CTSC国家队选拔赛  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解       题目描述 Description 错 ...

  4. EasyNVR无插件直播服务器软件览器低延时播放监控摄像头视频(EasyNVR播放FLV视频流)

    背景描述 EasyNVR的使用者应该都是清楚的了解到,EasyNVR一个强大的功能就是可以进行全平台的无插件直播.主要原因在于rtsp协议的视频流(默认是需要插件才可以播放的)经由EasyNVR处理可 ...

  5. SpringMVC spring-servlet.xml配置

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  6. 【python】-- 类的反射

    反射 反射我们以后会经常用到,这个东西实现了动态的装配,通过字符串来反射类中的属性和方法 一.反射函数 1.hasarttr(obj,name_str) 作用:判断一个对象obj中是否有对应的name ...

  7. 【python】-- web开发之DOM

    DOM 文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是, ...

  8. ElasticSearch(十七)初识倒排索引

    现在有两条document: doc1:I really liked my small dogs, and I think my mom also liked them. doc2:He never ...

  9. [note]一类位运算求最值问题

    [note]一类位运算求最值问题 给定一些数,让你从中选出两个数a,b,每次询问下列中的一个 1.a and b的最大值 2.a xor b的最大值 3.a or b的最大值 神仙们都是FWT,小蒟蒻 ...

  10. Data Structure Array: Program for array rotation

    http://www.geeksforgeeks.org/array-rotation/ O(n), O(1) #include <iostream> #include <vecto ...