【倍增】【线段树】雨林跳跃(luogu 7599[APIO 2021 T2])

正题

luogu 7599[APIO 2021 T2]


题目大意

给你一排树中每棵树的高度,每次跳跃可以跳到左/右边第一棵比该树高的树,问你从A-B中某棵树跳到C-D中的某棵树的最小步数(A⩽B<C⩽DA\leqslant B< C\leqslant DAB<CD


解题思路

在这里插入图片描述

上图为例,绿色为起点,蓝色为终点

对于起点,不难发现,要选择低于最高终点的点中尽量高度,且右边的起点都比它低

低于最高终点保证了可以跳到终点,而最高的保证了跳的步数尽可能少,如果右边有比它高的,通过前面的性质,可以发现无法跳到终点(用倍增实现)

起点确定之后考虑往左右跳,由于A⩽B<C⩽DA\leqslant B< C\leqslant DAB<CD,往终点走一定是往右跳

那么往左有什么意义呢,对于4,2,3,4,5,当位于2时,往右跳到5要3步,而先往左跳一步只要两步,由此,往左跳的高度如果大于右边若干树的高度,那么往左跳可以使答案跟优

那么把跳跃分成往上和往右两步,设fji,jfj_{i,j}fji,j为位于i向上跳2j2^j2j步的最高高度,因为跳到右边可以使往右跳少一步,所以往上跳一定能使往右跳步数减少,且跳得越高,少得越多

所以往上跳跳到第一个点,使得该点高于起点终点之间的所有点,然后往右跳即可


代码

#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define NN 200021
using namespace std;
int n, m, v, x, A, B, C, D, lg, bg, hed, top, ans;
int h[NN], d[NN], lj[NN][20], rj[NN][20], hj[NN][20];
struct node
{int v, s;bool operator <(const node &b) const{return s > b.s;}
}b[NN];
struct Tree//线段树找最大
{int a[NN<<2];#define ls x*2#define rs x*2+1void build(int x, int l, int r){if (l == r){a[x] = h[l];return;}int mid = l + r >> 1;build(ls, l, mid);build(rs, mid + 1, r);a[x] = max(a[ls], a[rs]);return;}int ask(int x, int L, int R, int l, int r){if (L == l && R == r) return a[x];int mid = L + R >> 1;if (r <= mid) return ask(ls, L, mid, l, r);else if (l > mid) return ask(rs, mid + 1, R, l, r);else return max(ask(ls, L, mid, l, mid), ask(rs, mid + 1, R, mid + 1, r));}
}T;void init(int N, std::vector<int> H)
{n = N;int lg = log2(n);for (int i = 1; i <= n; ++i){h[i] = H[i - 1];b[i].v = i;b[i].s = h[i];lj[i][0] = i;for (int j = 1; j <= log2(i); ++j)//向左跳,找起点,存的是最高高度if (h[lj[i][j - 1]] > h[lj[i - (1<<(j - 1))][j - 1]]) lj[i][j] = lj[i][j - 1];else lj[i][j] = lj[i - (1<<(j - 1))][j - 1];}for (int i = 1; i <= n; ++i)//向高跳{while(h[d[top]] < h[i] && top) top--;hj[i][0] = d[top];d[++top] = i;}top = 0;for (int i = n; i > 0; --i){while(h[d[top]] < h[i] && top) top--;if (h[hj[i][0]] < h[d[top]]) hj[i][0] = d[top];rj[i][0] = d[top];for (int j = 1; j <= lg; ++j)//向右跳rj[i][j] = rj[rj[i][j - 1]][j - 1];d[++top] = i;}sort(b + 1, b + 1 + n);for (int i = 1; i <= n; ++i)for (int j = 1; j <= lg; ++j)hj[b[i].v][j] = hj[hj[b[i].v][j - 1]][j - 1];//倍增T.build(1, 1, n);
}int minimum_jumps(int A, int B, int C, int D)
{A++;B++;C++;D++;lg = log2(n);hed  = T.ask(1, 1, n, C, D);if (B + 1 <= C - 1) v = T.ask(1, 1, n, B + 1, C - 1);else{if (h[B] < hed) return 1;return -1;}if (v > hed) return -1;x = B;bg = B;for (int i = lg; i >= 0; --i)if (h[lj[x][i]] <= hed && x - (1<<i) + 1 >= A){if (h[bg] < h[lj[x][i]]) bg = lj[x][i];//找起点x -= (1<<i);}ans = 0;for (int i = lg; i >= 0; --i)if (hj[bg][i] && h[hj[bg][i]] < v){bg = hj[bg][i];//向高跳ans += (1<<i);}if (hj[bg][0] && h[hj[bg][0]] < hed && h[bg] < v){bg = hj[bg][0];ans++;}for (int i = lg; i >= 0; --i)if (rj[bg][i] && rj[bg][i] < C)//向右跳{bg = rj[bg][i];ans += (1<<i);}if (h[bg] <= hed) return ans + 1;else return -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Duration(2020多校第二场D)

Duration&#xff08;2020多校第二场D&#xff09; 文章目录题意题解代码首先&#xff0c;非常感谢出题人出这个题&#xff0c;避免了我全wa的尴尬题意 求两个时间相差多少秒&#xff0c;两个时间为同一天 题解 全部转化成秒&#xff0c;然后求差 代码 #include<bits/s…

dotnetClub 的前世今生

三年之前&#xff0c;我做过一个在线调查&#xff0c;当时有不少人还是对一个在线社区表示出期待。.NET Core 技术正风声水起&#xff0c;所以我就开始了用它来开发一个论坛的计划。最近正式将项目推动到了一个 MVP 的状态。感兴趣的朋友&#xff0c;现在可以访问 preview.dotn…

P3308-[SDOI2014]LIS【最小割】

正题 题目链接:https://www.luogu.com.cn/problem/P3308 题目大意 三个nnn个数字的序列A,B,CA,B,CA,B,C。要求删除其中某些位置iii使得AAA的最长上升子序列至少减少111且删去位置BBB的权值和最小的情况下满足删去位置的CCC值升序排序后字典序最小。 解题思路 首先BBB值最小很…

Codeforces Round #656 (Div. 3)

A.Three Pairwise Maximums 首先最大的在原序列中肯定出现至少两次否则不能构造&#xff0c;即min max max&#xff0c;对于答案min min max肯定满足题意 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm>…

【LCT】网络(luogu 2173/ZJOI2011)

正题 luogu 2173 题目大意 给你一个图&#xff0c;每条边有有一种颜色&#xff08;numcolor⩽10num_{color}\leqslant 10numcolor​⩽10&#xff09;&#xff0c;保证以下性质&#xff1a; 1.一个点连出的同色边数不大于2 2.不存在同色边组成的环 现在让你进行3钟操作&…

【每日一题】7月13日题目精讲—Kingdom

【每日一题】7月13日题目精讲—Kingdom 文章目录题目描述题解&#xff1a;代码:时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 X王国有n位官员&#xff0c;编号从1到n。国…

P3309-[SDOI2014]向量集【线段树,凸壳】

正题 题目链接:https://www.luogu.com.cn/problem/P3309 题目大意 nnn个操作 在序列末尾加入一个向量(x,y)(x,y)(x,y)询问加入的第l∼rl\sim rl∼r个向量中的一个向量和(x,y)(x,y)(x,y)的点积最大值 强制在线&#xff0c;点积的定义为x1x2y1y2x_1x_2y_1y_2x1​x2​y1​y2​ …

CanalSharp-mysql数据库binlog的增量订阅消费组件Canal的.NET客户端

一.前言CanalSharp是阿里巴巴开源项目mysql数据库binlog的增量订阅&消费组件 Canal 的.NET客户端&#xff0c;关于什么是 Canal&#xff1f;又能做什么&#xff1f;我会在后文为大家一一介绍。CanalSharp 这个项目&#xff0c;是由我和 WithLin(主要贡献) 完成&#xff0c;…

Codeforces Round #657 (Div. 2)

A. Acacius and String 爆零&#xff01;太菜了&#xff0c;下来终于把A题代码调AC了 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace…

【树链剖分】软件管理(luogu 2146/金牌导航 树链剖分-2)

正题 luogu 2146 金牌导航 树链剖分-2 题目大意 有若干软件&#xff0c;除了软件0&#xff0c;所有软件都依赖且只依赖于另外一个软件 当要删除一个软件时&#xff0c;所有依赖于该软件的软件都要删掉 当安装一个软件时&#xff0c;该软件依赖的软件都要安装 问你每次操作…

【每日一题】7月14日题目精讲—压缩

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 给一个由小写字母组成的字符串&#xff0c;我们可以用一种简单的方法来压缩其中的重复…

P3306-[SDOI2013]随机数生成器【BSGS】

正题 题目链接:https://www.luogu.com.cn/problem/P3306 题目大意 给出一个p,a,b,x1,tp,a,b,x_1,tp,a,b,x1​,t&#xff0c;有xiaxi−1bx_iax_{i-1}bxi​axi−1​b 求一个最小的nnn使得xntx_ntxn​t 解题思路 下标缩一下先变成x0x_0x0​会更好算一点&#xff0c;只考虑x0x_0…

【DevOps+LIVE】直播复盘 – DevOps能力成长模型2018首发

昨天晚上小编和DevOpsDays中国核心组织者刘征老师和张乐老师一起嗨了一把&#xff0c;本来规划进行1小时的直播结果延长到了2个小时才结束&#xff0c;观众人数在前半段一直处于增长状态&#xff0c;直到开播一小时到达顶峰。小伙伴也非常给力&#xff0c;一共提出了40多个问题…

Codeforces Round #658 (Div. 2)

A - Common Subsequence 最短相同子序列长度肯定为1&#xff0c;如果一个元素都不相等之间不存在相同子序列 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include…

【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)

正题 luogu 2486 金牌导航 树链剖分-3 题目大意 给你一棵树&#xff0c;让你进行以下操作&#xff1a; 1.把一条路径染上一个颜色 2.查询一条路径上有多少个颜色段 解题思路 用树链剖分把问题转化为链上问题 然后维护一下左右端点颜色和颜色总数就好了 代码 #include<c…

小小粉刷匠

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld题目描述 “lalala,我是一个快乐的粉刷匠”,小名一边快活地唱着歌,一边开心地刷着墙",兴致突…

P5363-[SDOI2019]移动金币【阶梯博弈,dp,组合数学】

正题 题目链接:https://www.luogu.com.cn/problem/P5363 题目大意 1n1\times n1n的网格上有mmm个硬币&#xff0c;两个人轮流向前移动一个硬币但是不能超过前一个硬币&#xff0c;无法移动者输。 求有多少种情况先手必胜。 解题思路 竟然有我会的题&#xff0c;我感动 位置做…

M-SOLUTIONS Programming Contest 2020总结

A - Kyu in AtCoder 直接模拟 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include<iostream> #include<algorithm> using namespace std; int main(…

Emit动态代理.NetCore迁移之旅

前言】前面我们介绍了Aop 从静态代理到动态代理&#xff1a;https://www.cnblogs.com/7tiny/p/9657451.html我们在.NetFramework平台下使用微软提供的Emit技术实现了动态代理类的生成。但是.NetCore作为微软.Net平台的春天&#xff0c;如果类库光支持.NetFramework&#xff0c;…

【LCT】弹飞绵羊(luogu 3203/金牌导航 LCT-2)

正题 luogu 3203 金牌导航 LCT-2 题目大意 给你n个格子&#xff0c;当你在第i个格子时&#xff0c;可以往后跳aia_iai​格&#xff0c;让你进行几下操作&#xff1a; 1.修改第i个数 2.查询在第i个格子跳多少下会跳出界 解题思路 往后跳相当于连接格子&#xff0c;由此建立一…