对权值线段树剪枝的误解--以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 输出当前最小值,若不存 ...
随机推荐
- Node.js 模块系统入门
在编程领域中,模块是自包含的功能单元,可以跨项目共享和重用.它们使开发人员的生活更加轻松,因为我们可以使用它来增加应用程序的功能,而不必亲自编写这些功能.它还让我们可以组织和解耦代码,从而使应用程序更 ...
- Oracle表空间概述及其基本管理
最近在工作中遇到有同事对Oracle表空间的理解有问题,所以写了这篇文章.我会从概念,管理及特别需要关注的点等几个维度对表空间进行一些介绍.本文以介绍表空间为主,涉及到的其他概念不展开描述.有问题的地 ...
- JVM之GC(一)
Java较C而言,最大的区别在于内存管理.JVM设有无用内存空间自动回收复用机制,也就是我们所说的GC. 之前说过,栈是为线程.为函数的执行分配内存的地方,用完即“销毁”,这里留待以后做深入探讨:堆是 ...
- KindEditor.ready 不执行的解决方法
问题描述 按照官网的要求,一一都设置好了,但就是没法显示富文本编辑器. 1.设置好textarea输入框 <textarea id="myEditor" name=" ...
- 使用gravatar生成头像
avatar代表您在线的图像,当你与网站互动时,你的名字旁边会出现一张图片. Gravatar是一个全球通用的头像.你只需上传一次并创建自己的个人资料,然后当你加入任何支持Gravatar的网站时,你 ...
- 1z0-062 题库解析1
You configured the Fast Recovery Area (FRA) for your database. The database instance is in archivelo ...
- 【Leetcode 做题学算法周刊】第七期
首发于微信公众号<前端成长记>,写于 2020.01.15 背景 本文记录刷题过程中的整个思考过程,以供参考.主要内容涵盖: 题目分析设想 编写代码验证 查阅他人解法 思考总结 目录 12 ...
- 数字任意组合 - gcd
链接:https://www.nowcoder.com/acm/contest/160/A来源:牛客网 题目描述有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上a1,a2,...,an ...
- Microsoft Visual Studio提示正忙如何解决
打开项目的时候会一直提示正在加载,然后卡死,点击VS界面即出现下如图- 如图: 解决方法: 1.打开项目 找到一个叫vs的文件夹, 2.找到一个后缀是.suo的文件 把它删掉 3.关闭VS进程 重新打 ...
- python的requests用法详解
Requests是一个Python语言写的http相关设置或者请求的一个库 安装:pip install Requests或者pip3 install requests 使用的时候要import re ...