[ONTAK2010] Peaks 加强版
[ONTAK2010] Peaks 加强版
题目大意:原题变为强制在线查询
Solution
- 读入山高,排序后依然建立树链,初始化并查集,初始化重构树新节点标号为\(n+1\)
- 读入边,按照边权从小到大排序
- \(kruskal\)重构树
- 如果是在同一并查集里,\(continue\)
- 如果不在,建立新节点,两个节点的\(a\)都是新节点,并且记录在重构树上的\(fa\),合并树链
- 倍增处理重构树
- 读入询问,如果上一次询问的答案不为\(-1\),\(xor\)上一次的答案,在重构树上跳,查询答案
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define pf(x) printf("%d\n", x);
using std::sort;
const int X = 3400000 + 5;
const int M = 5e5 + 5;
const int N = 1e5 + 10;
int n, m, q, node, cnt, lastans = 0;
int sum[X], lson[X], rson[X], kfa[N << 1], ju[N << 1][18], val[N], fa[N << 1], root[N << 1];
struct Hill{
int id, hi;
bool operator < (const Hill &cmp) const {
return hi < cmp.hi;
}
}h[N];
struct Aha{
int a, b, c;
bool operator < (const Aha &cmp) const {
return c < cmp.c;
}
}a[M];
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void insert(int &cur, int l, int r, int p){
if(!cur) cur = ++cnt;
sum[cur]++;
if(l == r) return;
int mid = l + ((r - l) >> 1);
if(p <= mid) insert(lson[cur], l, mid, p);
else insert(rson[cur], mid + 1, r, p);
}
void merge(int &cur, int x, int y, int l, int r){
if(!cur) cur = ++cnt;
sum[cur] = sum[x] + sum[y];
if(l == r) return;
int mid = l + ((r - l) >> 1);
if(lson[x] && lson[y]) merge(lson[cur], lson[x], lson[y], l, mid);
else if(lson[x]) lson[cur] = lson[x];
else if(lson[y]) lson[cur] = lson[y];
if(rson[x] && rson[y]) merge(rson[cur], rson[x], rson[y], mid + 1, r);//1, mid
else if(rson[x]) rson[cur] = rson[x];
else if(rson[y]) rson[cur] = rson[y];
}
int query(int cur, int l, int r, int p){
if(l == r){
return h[l].hi;//
}
int mid = l + ((r - l) >> 1);
if(p <= sum[lson[cur]]) return query(lson[cur], l, mid, p);
else return query(rson[cur], mid + 1, r, p - sum[lson[cur]]);
}
inline int jump(int &x, int y){
for(int i = 17; i >= 0; --i)
if(ju[x][i] && val[ju[x][i] - n] <= y){
x = ju[x][i];
}
return x;
}
int main(){
scanf("%d %d %d", &n, &m, &q);
for(int i = 1; i <= n; ++i)
scanf("%d", &h[i].hi), h[i].id = i, fa[i] = i;
sort(h + 1, h + n + 1);
for(int i = 1; i <= n; ++i)
insert(root[h[i].id], 1, n, i);
node = n;
for(int i = 1; i <= m; ++i)
scanf("%d %d %d", &a[i].a, &a[i].b, &a[i].c);
sort(a + 1, a + 1 + m);
for(int i = 1, fx, fy; i <= m; ++i){
fx = find(a[i].a);
fy = find(a[i].b);
if(fx == fy) continue;
fa[++node] = fa[fx] = fa[fy] = kfa[fx] = kfa[fy] = node;
val[node - n] = a[i].c;
merge(root[node], root[fx], root[fy], 1, n);
}
for(int i = 1; i <= node; ++i) ju[i][0] = kfa[i];
for(int j = 1; j <= 17; ++j)
for(int i = 1; i <= node; ++i)// i <= n 以及顺序
ju[i][j] = ju[ju[i][j - 1]][j - 1];
int la, lb, lc;
while(q--){
scanf("%d %d %d", &la, &lb, &lc);
if(lastans != -1) la ^= lastans, lb ^= lastans, lc ^= lastans;
int u = jump(la, lb);
if(sum[root[u]] < lc) lastans = -1;
else lastans = query(root[u], 1, n, sum[root[u]] - lc + 1);
printf("%d\n", lastans);
}
return 0;
}
[ONTAK2010] Peaks 加强版的更多相关文章
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- 【BZOJ3551】 [ONTAK2010]Peaks加强版
BZOJ3551 [ONTAK2010]Peaks加强版 Solution Kruscal重构树后发现可以对于小于的离散化然后倍增+主席树找到上一个的可行解. 然后就可以了. 如果数组开的不好,容易在 ...
- 【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树
[BZOJ3545][ONTAK2010]Peaks Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困 ...
- 3551: [ONTAK2010]Peaks加强版
3551: [ONTAK2010]Peaks加强版 https://www.lydsy.com/JudgeOnline/problem.php?id=3551 分析: kruskal重构树 + 倍增 ...
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2438 Solved: 763[Submit][ ...
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- bzoj 3551: [ONTAK2010]Peaks加强版
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- ONTAK2010 Peaks加强版(离线&在线)
题面 弱化版:luogu 强制在线版:bzoj 题解 本题有两种解法 离线算法:线段树合并 先看一道简单题[USACO18JAN]MooTube 本题就是在此基础上求第\(k\)高的点 首先把询问和路 ...
- BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)
Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...
随机推荐
- kubernetes进阶(二)核心网络插件Flannel
网络插件Flannel介绍:https://www.kubernetes.org.cn/3682.html 首先,flannel利用Kubernetes API或者etcd用于存储整个集群的网络配置, ...
- WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS
title: WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS date: 2020-03-20 10:43:00 categories: acm tags: [ ...
- 缓冲区溢出实验 5 Snprintf
实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul5 Snprintf函数,百度百科: 将可变个参数(...)按照format ...
- 牛客网多校第5场 H subseq 【树状数组+离散化】
题目:戳这里 学习博客:戳这里 题意:给n个数为a1~an,找到字典序第k小的序列,输出该序列所有数所在位置. 解题思路:先把所有序列预处理出来,方法是设一个数组为dp,dp[i]表示以i为开头的序列 ...
- 牛客网多校第4场 J Hash Function 【思维+并查集建边】
题目链接:戳这里 学习博客:戳这里 题意: 有n个空位,给一个数x,如果x%n位数空的,就把x放上去,如果不是空的,就看(x+1)%n是不是空的. 现在给一个已经放过数的状态,求放数字的顺序.(要求字 ...
- codeforces 6D
D. Lizards and Basements 2 time limit per test 2 seconds memory limit per test 64 megabytes input st ...
- sscanf的最基础用法(非原创)
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 int main(){ 6 ch ...
- github gist 无法访问
转自这里 以管理员身份在hosts文件: Windows: C:\Windows\System32\drivers\etc Ubuntu: /etc/hosts 添加: 192.30.253.118 ...
- 互联网公司技术岗实习/求职经验(实习内推+简历+面试+offer篇)
找工作的事基本尘埃落定了,打算把这大半年来积累的经验写下来,基本都是我希望当年找实习的时候自己能够知道的东西,帮师弟师妹们消除一点信息不平等,攒攒RP~ 不要像我当年那样,接到电话吓成狗,没接到电话吓 ...
- GitHub GraphQL API v4 & GitHub REST API v3
GitHub, GraphQL API, v4 ,REST API, v3, GraphQL, https://developer.github.com/v4/ https://developer.g ...