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

对于每组询问,输出一个整数表示答案。

有小于等于 $x$ 这个条件十分不好办 .

考虑离线,按照 $x$ 从小到大依次加入,查询的时候直接在 $splay$ 中查询第 $k$ 大即可.

#include <cstdio>
#include <algorithm>
#include <stack>
#define N 600005
#define inf 1000000002
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int splay_cnt;
namespace IO
{
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd()
{
int x=0;
char c=nc();
while(c<48) c=nc();
while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();
return x;
}
};
struct Edge
{
int u , v , c ;
}ed[N];
bool cmp(Edge a, Edge b)
{
return a.c < b.c;
}
struct Ask
{
int u , x , k , id ;
}as[N];
bool cmp2(Ask a, Ask b)
{
return a.x < b.x;
}
#define lson ch[x][0]
#define rson ch[x][1]
stack <int> S;
int answer[N], h[N], size[N], f[N], ch[N][2], siz[N], val[N], rt[N], p[N], mk = 0;
inline void init(int sz)
{
for(int i = 1; i <= sz ; ++i) S.push(i);
for(int i = 1; i <= sz ; ++i) p[i] = i, size[i] = 1;
}
int find(int x)
{
return p[x] == x ? x : p[x] = find(p[x]);
}
inline int newnode()
{
int u = S.top(); S.pop();
return u;
}
inline int get(int x)
{
return ch[f[x]][1] == x;
}
inline void pushup(int x)
{
siz[x] = siz[lson] + siz[rson] + 1;
}
inline void rotate(int x)
{
int old = f[x], fold = f[old], which = get(x);
ch[old][which] = ch[x][which ^ 1], f[ch[old][which]] = old;
ch[x][which ^ 1] = old, f[old] = x, f[x] = fold;
if(fold) ch[fold][ch[fold][1] == old] = x;
pushup(old), pushup(x);
}
inline void splay(int x, int &tar)
{
int u = f[tar];
for(int fa; (fa = f[x]) ^ u; rotate(x))
if(f[fa] ^ u)
rotate(get(fa) == get(x) ? fa : x);
tar = x;
}
inline int kth(int x, int k)
{
if(siz[x] < k) return inf;
while(1)
{
if(k > siz[rson])
{
k -= (siz[rson] + 1);
if(!k) return x;
else x = lson;
}
else x = rson;
}
}
inline void insert(int &x, int ff, int v)
{
if(!x)
{
mk = x = newnode();
f[x] = ff, val[x] = v, pushup(x);
return;
}
insert(ch[x][v > val[x]], x, v), pushup(x);
}
inline void DFS(int y, int x)
{
if(lson) DFS(y, lson);
if(rson) DFS(y, rson);
int v = val[x];
S.push(x), val[x] = siz[x] = lson = rson = f[x] = 0, insert(rt[y], 0, v), ++splay_cnt;
if(splay_cnt % 6 == 0) splay(mk, rt[y]);
}
inline void connect(int o)
{
int u = ed[o].u, v = ed[o].v;
int x = find(u), y = find(v);
if(x ^ y)
{
if(size[y] < size[x]) swap(x, y);
p[x] = y, size[y] += size[x], DFS(y, rt[x]);
}
}
int main()
{
using namespace IO;
// setIO("input");
int n, m, q, i, j;
n = rd(), m = rd(), q = rd(), init(n);
for(i = 1; i <= n ; ++i) h[i] = rd(), insert(rt[i], 0, h[i]);
for(i = 1; i <= m ; ++i) ed[i].u = rd(), ed[i].v = rd(), ed[i].c = rd();
sort(ed + 1, ed + 1 + m, cmp);
for(i = 1; i <= q ; ++i)
{
as[i].u = rd(), as[i].x = rd(), as[i].k = rd(), as[i].id = i;
}
sort(as + 1, as + 1 + q, cmp2);
for(i = j = 1; i <= q; ++i)
{
while(ed[j].c <= as[i].x && j <= m) connect(j), ++j;
int l = kth(rt[find(as[i].u)], as[i].k);
answer[as[i].id] = (l == inf ? inf : val[l]);
if(l ^ inf)
{
++splay_cnt;
if(splay_cnt % 6 == 0) splay(l, rt[find(as[i].u)]);
}
}
for(i = 1; i <= q; ++i) printf("%d\n",answer[i] == inf ? -1 : answer[i]);
return 0;
}

  

BZOJ 3545: [ONTAK2010]Peaks 启发式合并 + 离线 + Splay的更多相关文章

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

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

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

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

  3. ●BZOJ 3545 [ONTAK2010]Peaks(离线)

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3545 http://www.lydsy.com/JudgeOnline/problem.ph ...

  4. BZOJ.3545.[ONTAK2010]Peaks(线段树合并)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...

  5. bzoj 3545: [ONTAK2010]Peaks

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1124  Solved: 304[Submit][Status][Discuss] Descripti ...

  6. bzoj 3545: [ONTAK2010]Peaks Kruskal重构树

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

  7. 【loj6041】「雅礼集训 2017 Day7」事情的相似度 后缀自动机+STL-set+启发式合并+离线+扫描线+树状数组

    题目描述 给你一个长度为 $n$ 的01串,$m$ 次询问,每次询问给出 $l$ .$r$ ,求从 $[l,r]$ 中选出两个不同的前缀的最长公共后缀长度的最大值. $n,m\le 10^5$ 题解 ...

  8. BZOJ.3510.首都(LCT 启发式合并 树的重心)

    题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz ...

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

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

随机推荐

  1. 2019JAVA第四次实验报告

    JAVA实验报告 班级 计科二班 学号 20188442 姓名 吴怡君 完成时间 2019/9/29 评分等级 实验四 类的继承 1.实验目的 掌握类的继承方法: 变量的继承和覆盖,方法的继承.重载和 ...

  2. HTML简单介绍(个人角度)

    之前对HTML的理解:HTML主要是标签组成,一对标签组成一个位置,在响应的位置内填写对应的内容. 1.编译工具 [ ] HTML需要编译工具?txt文档改后缀双击运行. [ ] 了解前端了一下前端, ...

  3. IIS服务搭建 试图加载格式不正确的程序

    1.基础步骤 https://jingyan.baidu.com/article/fedf073770f23335ac8977b1.html 2.错误解决 试图加载格式不正确的程序   解决:在IIS ...

  4. ORA-01406:提取的列值被截断 ; SQL Server :将截断字符串或二进制数据

    oracle 数据库可以正常连接,表数据也可以正常读取, 但在程序中相同的位置,有时会报错,有时不会报错,有的电脑会报错,有的不会 报错内容为 ORA-01406:提取的列值被截断 查了网上提供的一些 ...

  5. laravel5.5入门-安装和认证

    一.安装 在终端CMD里切换到你想要放置该网站的目录下(如 d:\project\laravel),运行命令 composer create-project laravel/laravel learn ...

  6. 3-关于ES的几个小疑问和解答

    1.ES如何实现分布式 2.ES如何实现高实时 3.ES如何实现高扩展 4.ES7.x版本为何废弃type 5.搜索原理--知乎es

  7. Python基础——函数进阶

    等待更新…………………… 后面再写

  8. python 父子节点生成字典

    lines = [(1, 1, '父1节点'), (2, 1, '1-2'), (3, 1, '1-3'), (4, 3, '1-3-4'), (5, 3, '1-3-5'), (6, 3, '1-3 ...

  9. oracle分页查询按日期排序失败问题

    今天对已经上线的代码进行测试,结果发现分页是失效的,一度怀疑是前台页面分页失效,排查后发现是分页sql有问题,分页sql按日期排序,导致分页失败. 按日期排序,会造成相同的数据重复出现. 解决方案:在 ...

  10. 学习-Pytest(三)setup/teardown

    1. 用例运行级别 模块级(setup_module/teardown_module)开始于模块始末,全局的 函数级(setup_function/teardown_function)只对函数用例生效 ...