3551: [ONTAK2010]Peaks加强版

https://www.lydsy.com/JudgeOnline/problem.php?id=3551

分析:

  kruskal重构树 +  倍增 + 主席树。

  首先建立kruskal重构树,那么查询就变成了,在kruskal重构树上找倍增找到最上面的权值小于x的点(节点的权值为原图的边权),那么这棵树内的所有点都可以在经过权值小于x的点相互到达,所以在这棵树内查询第k大即可。dfs序后,变成序列上的问题,查询区间的第k大。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Edge{
int u, v, w;
bool operator < (const Edge &A) const {
return w < A.w;
}
}e[];
int fa[N << ], f[N << ][], mx[N << ], st[N << ], pos[N << ], en[N << ], val[N], disc[N]; // mx[N<<1]
int sum[N * ], ls[N * ], rs[N * ], Root[N << ]; // 乘18,不要17
int n, m, Q, tot, Time_Index, tot_node;
vector<int> T[N << ]; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1 int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void Kruskal() {
for (int i=; i<=n+n; ++i) fa[i] = i;
sort(e + , e + m + );
int cntedge = ; tot = n;
for (int i=; i<=m; ++i) {
int u = find(e[i].u), v = find(e[i].v);
if (u == v) continue;
++tot;
fa[u] = tot, fa[v] = tot;
f[u][] = tot, f[v][] = tot;
mx[tot] = e[i].w;
T[tot].push_back(u), T[tot].push_back(v);
// if (++cntedge == n + n - 1) break; // n + n - 1
}
}
void dfs(int u,int fa) {
st[u] = ++Time_Index;
pos[Time_Index] = u;
for (int sz=T[u].size(),i=; i<sz; ++i) {
int v = T[u][i];
if (v == fa) continue;
dfs(v, u);
}
en[u] = Time_Index;
}
void update(int l,int r,int &rt,int last,int p) {
rt = ++tot_node;
sum[rt] = sum[last] + ;
ls[rt] = ls[last], rs[rt] = rs[last];
if (l == r) return ;
int mid = (l + r) >> ;
if (p <= mid) update(l, mid, ls[rt], ls[last], p);
else update(mid + , r, rs[rt], rs[last], p);
}
int query(int l,int r,int Head,int Tail,int k) {
if (sum[Tail] - sum[Head] < k) return -;
if (l == r) return l;
int mid = (l + r) >> , cnt = sum[ls[Tail]] - sum[ls[Head]];
if (cnt >= k) return query(l, mid, ls[Head], ls[Tail], k);
else return query(mid + , r, rs[Head], rs[Tail], k - cnt);
}
int main() {
n = read(), m = read(), Q = read();
for (int i=; i<=n; ++i) val[i] = read(), disc[i] = val[i];
for (int i=; i<=m; ++i)
e[i].u = read(), e[i].v = read(), e[i].w = read(); sort(disc + , disc + n + );
int cnt = ;
for (int i=; i<=n; ++i) if (disc[i] != disc[cnt]) disc[++cnt] = disc[i]; // i=2
for (int i=; i<=n; ++i) val[i] = lower_bound(disc + , disc + cnt + , val[i]) - disc; Kruskal();
dfs(tot, ); for (int j=; j<=; ++j)
for (int i=; i<=tot; ++i) f[i][j] = f[f[i][j-]][j-]; for (int i=; i<=tot; ++i) {
if (pos[i] > n) Root[i] = Root[i - ];
else update(, cnt, Root[i], Root[i - ], val[pos[i]]); // val[pos[i]] !!!
} int lastans = ;
while (Q--) {
int v = read(), x = read(), k = read();
if (lastans != -) v ^= lastans, x ^= lastans, k ^= lastans;
for (int i=; i>=; --i)
if (f[v][i] && mx[f[v][i]] <= x) v = f[v][i];
int l = st[v], r = en[v];
k = sum[Root[r]] - sum[Root[l]] - k + ;
if (k <= ) { puts("-1"); lastans = -; continue; }
int p = query(, cnt, Root[l], Root[r], k);
if (p == -) { puts("-1"); lastans = -; continue; }
printf("%d\n",lastans = disc[p]);
}
return ;
}

3551: [ONTAK2010]Peaks加强版的更多相关文章

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

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

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

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

  3. bzoj 3551: [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  4. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  5. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

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

  6. 【刷题】BZOJ 3551 [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

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

    建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...

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

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

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

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

随机推荐

  1. ejb3persistence.jar javax.persistence的注解配置

    JPA注解持久化类很方便,需要jar包:ejb3-persistence.jar.我用以下三个类来说明用法.  sh原创 转载请注明: http://67566894.iteye.com/blog/6 ...

  2. [USACO19JAN]Exercise Route

    题目 这题的数据有点水,暴力合并\(set\)好像过了 分析一下这个题的性质,发现我们一条非树边就会形成一个环,而我们要求选择两个非树边,就会形成两个环,要求不走重复的点,就是说我们需要走一个大环,且 ...

  3. 使用QT开发GoogleMap瓦片显示和下载工具

    之前做项目的时候经常遇到需要大量地图背景数据,然后没有数据被逼着去Google上下载瓦片数据在拼接成整张影像的工作,其实遥感影像晚上有很多可以下载到的,但是大部分是作为研究用的,作为GIS的背景图或者 ...

  4. iOS之3DTouch的使用---很简单,看我就够啦~~

    3DTouch是苹果在iOS9之后新推出的功能,功能大致可以分成两种,一种是长按app的icon,会出现以下的界面,还有一种是在app内部的某个视图上使用,效果如下图. 详细的效果也可以参见微信.微信 ...

  5. 【luogu P2919 [USACO08NOV]守护农场Guarding the Farm】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2919 1.搜索的时候分清楚全局变量和局部变量的区别 2.排序优化搜索 #include <cstdio ...

  6. $Yeasion$的码风修改历程

    总之,今天是一个值得纪念的伟大日子,我将自己的码风进行了彻底的修改,大概是参考了Pks和\(Rqy\)的码风,分为以下几点. 1.变量名.在所有的计算符号之前和之后加空格.如:"&& ...

  7. Oracle 体系结构二 内存结构

    Oracle实例由共享内存块(SGA)以及大量的后台进程构成. SGA必须包含的数据结构: 数据库缓冲区缓存 日志缓冲区 共享池 可选的数据结构: 大池 JAVA池 流池 其他缓冲区缓存池 用户会话还 ...

  8. OC中property方法的使用

    我们直入主题,关于property方法,我们先来了解一下相关的知识,首先是成员变量,实例变量,属性变量. 我们定义一个类来看一下 @interface Person :NSObject{ NSInte ...

  9. C++ Primer学习笔记_1_快速入门

    C++快速入门 一 编写简单程序 // main是操作系统唯一显示调用的函数int main() {/**return返回的值是一个状态指示器 0:成功 非0:返回错误给OS*以echo $?命令可以 ...

  10. UDP实现网络通信程序

    VC6.0创建基于UDP协议的网络聊天程序 只有一个工程UDP,服务器和客户端都是这个工程,因为UDP中C/S区分不强化 只讲关键部分,避免累赘 1.为对话框添加控件 2.为控件绑定变量和消息函数 启 ...