正题

题目链接:https://www.luogu.com.cn/problem/P7599


题目大意

nnn棵树,在某棵树上时可以选择向左右两边第一棵比它高的树跳,现在qqq次询问从[A,B][A,B][A,B]中某个点出发跳到[C,D][C,D][C,D]中某个点的最少次数。

1≤n≤2×1051\leq n\leq 2\times 10^51≤n≤2×105


解题思路

考虑到主要的阈值[B+1,C−1][B+1,C-1][B+1,C−1]中的最大值,一旦超过了这个值就只需要考虑是否大于[C,D][C,D][C,D]中的最大值就好了。

那么我们考虑如何选取起点,首先我们显然不能超过[C,D][C,D][C,D]中的最大值mxmxmx,在这一情况下我们需要找到一个最大的位置小于mxmxmx且在它后面没有比mxmxmx大的数(否则就跳不过去了),这个过程我们用二分加STSTST表可以实现。

然后考虑选取起点如何跳跃,首先如果[B+1,C−1][B+1,C-1][B+1,C−1]中的最大值limlimlim远大于起点的话我们肯定是优先考虑跳左右两边高的那个点,这样肯定是最优的。所以我们在不大于limlimlim的情况下肯定是选取这种跳法。对于这样的跳跃我们处理出一棵树然后在上面倍增即可。

然后当跳到最后一个小于limlimlim的值时我们有两种方法,一种是继续这样跳此时我们的值大于limlimlim了可以直接跳过[B+1,C−1][B+1,C-1][B+1,C−1]但是需要判断这个值是否小于mxmxmx。(否则就顺便跳过了[C,D][C,D][C,D])。

第二种方法是直接一直往右边跳直到到[C,D][C,D][C,D]段,这个我们的处理方法可以每个点向它右边比它大的第一个点连边,然后limlimlim肯定在起点到根的路径上,直接用深度减去即可。

记得判无解

时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2e5+10,T=18;
int n,q,h[N],p[N],l[N],r[N],lg[N];
int f[N][T],g[N][T],dep[N];
int RMQ(int l,int r){if(l>r)return 0;int z=lg[r-l+1];return max(f[l][z],f[r-(1<<z)+1][z]);
}
void init(int N,std::vector<int> H) {n=N;h[0]=n+1;for(int i=1;i<=n;i++)h[i]=H[i-1],p[h[i]]=i,f[i][0]=h[i];for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;for(int j=1;(1<<j)<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);for(int i=1;i<=n;i++)l[i]=i-1,r[i]=i+1;for(int i=1;i<=n;i++){int x=p[i];r[l[x]]=r[x];l[r[x]]=l[x];g[x][0]=(h[l[x]]>h[r[x]])?l[x]:r[x];}for(int j=1;j<T;j++)for(int i=1;i<=n;i++)g[i][j]=g[g[i][j-1]][j-1];for(int i=n;i>=1;i--)dep[i]=dep[r[i]]+1;
}
int minimum_jumps(int A,int B,int C,int D){A++;B++;C++;D++;int l=A,r=B;int lim=RMQ(B+1,C-1),zc=RMQ(C,D);if(RMQ(B,C-1)>zc)return -1;while(l<=r){int mid=(l+r)>>1;if(RMQ(mid,B)>zc)l=mid+1;else r=mid-1;}int x=p[RMQ(l,B)],ans=0;if(h[x]>lim)return 1;for(int i=T-1;i>=0;i--)if(h[g[x][i]]<lim)x=g[x][i],ans+=(1<<i);if(g[x][0]&&h[g[x][0]]<zc&&h[x]<lim)ans+=2;else ans+=dep[x]-dep[p[lim]]+1;return ans;
}
//vector<int> H;
//int main()
//{//  scanf("%d%d",&n,&q);
//  for(int i=0,x;i<n;i++)
//      scanf("%d",&x),H.push_back(x);
//  init(n,H);
//  while(q--){//      int A,B,C,D;
//      scanf("%d%d%d%d",&A,&B,&C,&D);
//      printf("%d\n",minimum_jumps(A,B,C,D));
//  }
//  return 0;
//}

P7599-[APIO2021]雨林跳跃【二分,倍增,ST表】相关推荐

  1. P7599 [APIO2021] 雨林跳跃

    封闭道路的题解呢? 考虑 A = B , C = D A=B,C=D A=B,C=D 只需要从 A A A开始每一步都跳最大的那个就好了!如果能跳到,说明 m a x [ B , C − 1 ] &l ...

  2. bzoj3277 串 (后缀数组+二分答案+ST表)

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  3. bzoj5308[Zjoi2018]胖(线段树,二分,st表)

    Description Cedyks是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks是一个富有的男孩子.他住在著名的ThePLace(宫殿)中. Cedyks是一个 ...

  4. poj3264Balanced Lineup(倍增ST表)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 52328   Accepted: 24551 ...

  5. 【cogs2711】jump,二分答案+倍增套ST表

    传送门 思路: 好久没写题解了来爽一发 还是比较有意思的一道题目 首先想到二分答案x,我们枚举每一个点i,点i在x步内所能到达的点显然能形成一个区间[L i ,R i ] [L_i,R_i],那么[1 ...

  6. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  7. 倍增算法入门 超详细解答+LCA+RMQ(ST表)+例题剖析

    目录 一.倍增算法 二.倍增算法的应用:求LCA(最近公共祖先)附模板题 三.倍增算法的应用:RMQ 问题(ST表)附模板题 一.倍增算法 要了解倍增之前,强烈建议大家先看一下这位大佬对倍增的解释:[ ...

  8. 倍增算法入门 超详细解答+LCA+RMQ(ST表)+例题剖析

    目录 一.倍增算法 二.倍增算法的应用:求LCA(最近公共祖先)附模板题 三.倍增算法的应用:RMQ 问题(ST表)附模板题 一.倍增算法 要了解倍增之前,强烈建议大家先看一下这位大佬对倍增的解释:[ ...

  9. BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】

    题目 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , 如名字所见,到处充满了数学的谜题. 现在你拥有n颗宝石,每颗宝石 ...

最新文章

  1. Python网络爬虫实战:天猫胸罩销售数据分析
  2. class文件打成jar包
  3. 学的php毫无兴趣,培训班学PHP,感觉兴趣越来越低,哎,真的很迷茫了!
  4. 【Java从0到架构师】Filter_Listener_AJAX
  5. 《人工智能如何走向新阶段》大家谈(跟帖,续)
  6. 苹果 SwiftUI 踢馆谷歌 Flutter!
  7. 计算机网络按信息传输介质的性能来划分,第3章 计算机网络基础和 Internet 应用...
  8. 图像分割学习笔记_1(opencv自带meanshift分割例子)
  9. 物流管理系统需要的服务器,物流业务管理系统
  10. golang学习(三)—— 数组、切片、map
  11. 树莓派3B+安装JupyterLab
  12. 云主机磁盘I/O %util飙高排查
  13. Python批量修改txt文件的某列数值
  14. 在Linux Mint上玩转蓝牙机械键盘
  15. 大学英语综合教程四 Unit 4 课文内容英译中 中英翻译
  16. 劫持网站防御技术,网站被劫持到其它网站的解决方法
  17. 开启Mac的壁纸自动更换功能
  18. 内核驱动隐藏【绕过PatchGuard】
  19. 关于layui、table数据表格请求异常回调函数
  20. Echarts 深色模式图表背景透明

热门文章

  1. python 空指针_Python&CType空指针错误
  2. 件工程项目开发最全文档模板_一文带你了解微信小程序社区和小程序开发
  3. linux安装卷管理,Linux安装管理ISCSI卷(initiator端)
  4. 前端对div连线_《前端图形学从入门到放弃》003 三维世界
  5. mysql非安装_mysql 非安装版的配置
  6. categories php,manage-categories.php
  7. 计算机算法音乐专业,音乐信号分析算法的乐理简说(非音乐专业的乐理)
  8. python getopt模块_python之getopt模块使用
  9. oracle计算最大与最小之间数,oracle 分析函数
  10. [mybatis]逆向工程MGB基本编写