对权值线段树剪枝的误解--以HDU6703为例
引子
对hdu6703,首先将问题转化为“询问一个排列中大于等于k的值里,下标超过r的最小权值是多少”
我们采用官方题解中的做法:权值线段树+剪枝
对(a[i],i)建线段树,查询权值线段树的[k,n]中第一个下标超过r的值
代码是这样的
int ask(int l, int r, int root){
int mid = (l+r)>>1;
if(mx[root]<=R)return -1;
if(l==r){return l;}
int ans = -1;
if(k<=mid)ans=ask(lson);
if(ans==-1)ans=ask(rson);
return ans;
}
这把辣鸡的我给看meng了:在R=n的时候,最坏情况下一直向左递归,并且没找到然后向右递归,再向右递归的同时又重复没找到,这个ask不就退化成O(n)的了吗?
思考
经过半个月的思考(被虐),我大概懂了这个剪枝
首先分析以下几个问题:
什么情况下才会递归下去?
由代码第三行的
if(mx[root]<=R)return -1;
我们可以知道,只有当前权值区间\((l,r)\)的最大下标超过R才可能存在答案
什么情况下会往左递归并且不会从左边的递归返回答案?
假设当前权值区间为\([l,r]\)
如果往左边递归没有O(1)返回的话,根据上面的结论,那么一定是因为左区间\([l,mid]\)存在一个下标大于R
但是,左区间中合法区间应该为\([max(k,l),mid]\) **
所以当\(k>l\),且答案均分布在\([l,k]\)时,才会向左递归并且不从左区间返回答案**
什么时候“错误的左区间递归”会结束?
假设最坏情况,答案在k-1里,k-1一直在做区间的递归中,只有递归到当l=k的时候,才会结束这个错误
由线段树的相关性质只可以知道,这个最坏情况可以到\(l=r=k\),也就是跑了一个\(O(logn)\)的链
深入思考
思考完以上几个问题,继续思考:
当走完这条错误链,回溯的时候,会回溯到哪里?
当然是第一次出现这个错误分叉的地方(其实就是父节点)
但是此时我们在左区间没找到答案,会去右区间,而右区间\([mid+1,r]\)是完全包含于合法区间\([k,n]\)中的,所以只会出现两种情况
1.右区间没有合法答案,O(1)退出,继续回溯
2.右区间有答案,最终答案必在右区间中
一旦出现了2,就是正常的没有限制\([k,n]\)的线段树找最小值的O(logn)的做法了
而1也只是一个普通的回溯,按照父节点回溯到最原始的错误分叉,答案就在另一条路中
这个问题就解决啦
结论
这个剪枝强无敌,最终询问操作的执行次数只有两条链
复杂度为O(logn)
对权值线段树剪枝的误解--以HDU6703为例的更多相关文章
- 2019年CCPC网络赛 HDU 6703 array【权值线段树】
题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP
2892: 强袭作战 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 45 Solved: 30[Submit][Status][Discuss] D ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- 动态求区间K大值(权值线段树)
我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...
- 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题
“队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄> 线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...
- 【BZOJ3685】【zkw权值线段树】普通van Emde Boas树
原题传送门 因为马上要开始搞树套树了,所以学了一波权值线段树...毕竟是会点zkw线段树的,所以zkw线段树大法好! 解题思路: 介绍一下权值线段树吧,其实感觉就是线段树的本义,就是你用线段树维护了数 ...
- BZOJ_2161_布娃娃_权值线段树
BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...
- BZOJ_3685_普通van Emde Boas树_权值线段树
BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存 ...
随机推荐
- JUC 中的 Atomic 原子类总结
1 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思.在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的.在我们这里 Atomic 是指一个操作是不可中断的.即使是 ...
- VS2019菜单栏没有团队选项解决方法
新安装了Visual Studio 2019结果菜单栏没有“团队”菜单,导致没办法连接TFS服务器,查了下网上也并没有对应解决方法(甚至遇见这个问题的都没有/笑哭,所以这个方法写出来也大概没什么用) ...
- invalid expression: missing ) after argument list in xxx 或者 console.error(("[Vue warn]: " + msg + trace));
效果图: 此处错误原因 中文输入法的 逗号 导致 : 解决方案: 改为 英文输入法的 逗号
- 重拾c++第一天(1):环境配置
时过多年,c++基本不记得了,故在此记录相关重拾记录. 学习语言第一步当然是环境配置了(笑),由于暂无用c++进行大型项目开发的需求,所以先下载dev进行过渡. 安装过程非常简单,值得注意的是配置时选 ...
- MySQL/数据库 知识点总结
书籍推荐 <SQL基础教程(第2版)> (入门级) <高性能MySQL : 第3版> (进阶) 文字教程推荐 SQL Tutorial (SQL语句学习,英文).SQL Tut ...
- Quartz定时任务整理
一. 介绍 Quartz是一个开源的定时任务调度框架,这里就不详细介绍了,我们直入主题Quartz主要由三部分组成 任务:JobDetail 触发器:Trigger,(分两类:SimpleTrigge ...
- Linux程序守护脚本
不废话,直接上脚本,[]注释的下发语句需要按需替换: #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/us ...
- Kivy 自定义控件之(一)
lableSlider1.kv文件 <LabelSlider>: orientation:'vertical' BoxLayout: MyLabelSlider: name: 'Slide ...
- Visual studio 2015 与 mysql 连接
Visual Studio 2015 Community连接到MySQL,步骤很简单,但刚弄的时候一脸. 这个学期开了一门课程,老师教的是visual studio 2010来开发.net的,但是我自 ...
- kuangbin专题专题十一 网络流 Going Home POJ - 2195
题目链接:https://vjudge.net/problem/POJ-2195 思路:曼哈顿距离来求每个人到每个房间的距离,把距离当作费用. 就可以用最小费用最大流来解决了,把每个房子拆成两个点,限 ...