引子

对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为例的更多相关文章

  1. 2019年CCPC网络赛 HDU 6703 array【权值线段树】

    题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...

  2. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  3. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  4. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  5. 动态求区间K大值(权值线段树)

    我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...

  6. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  7. 【BZOJ3685】【zkw权值线段树】普通van Emde Boas树

    原题传送门 因为马上要开始搞树套树了,所以学了一波权值线段树...毕竟是会点zkw线段树的,所以zkw线段树大法好! 解题思路: 介绍一下权值线段树吧,其实感觉就是线段树的本义,就是你用线段树维护了数 ...

  8. BZOJ_2161_布娃娃_权值线段树

    BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...

  9. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

随机推荐

  1. Spring中常见的设计模式——模板模式

    一.模板模式的应用场景 模板模式又叫模板方法模式(Template Method Pattern),指定义一个算法的骨架,并允许自雷为一个或者多个步骤提供实现.模板模式使得子类可以在不改变算法结果的情 ...

  2. spring boot使用拦截器

    1.编写一个拦截器 首先,我们先编写一个拦截器,和spring mvc方式一样.实现HandlerInterceptor类,代码如下 package com.example.demo.intercep ...

  3. JAVA并发之锁获取步骤及锁优化

    在另外的两篇文章中先后介绍了轻量级同步关键字volatile和重量级锁关键字synchronized,这两个关键字是Java语言中进行线程同步的基本方式(当然还有ReentrenLock等显式锁方式) ...

  4. Spring-Boot使用嵌入式容器,那怎么配置自定义Filter呢

    Listener.Filter和Servlet是Java Web开发过程中常用的三个组件,其中Filter组件的使用频率最高,经常被用来做简单的权限处理.请求头过滤和防止XSS攻击等.如果我们使用的是 ...

  5. 迷你PS小程序-集成的开放式画报、油墨电子签名、图片拖拽可单独食用

    米娜桑,哦哈哟~ 个人制作,该文章主要讲解最近基于uni-app框架编写的集图文拖拽等多方位编辑.油墨电子签名.开放式海报于一体的小程序的制作思路和实现代码. 目录 1.完整源码链接 2.实现思路 3 ...

  6. doc_values VS stored field

    doc_values 按列存储,按docId排序,在query阶段使用,直接根据docId获取具体field的value,用来排序,聚合等. stored field按文档存储,按docId排序,一条 ...

  7. 基于redis有序集合,实现简单的延时任务

    基于redis有序集合,实现简单的延时任务 延时任务的场景很多,开发过程中我们经常会遇到,比如说: 1.订单未付款,5分钟后自动取消,这是电商网站非常普遍的需求: 2.用户创建订单不付款,3分钟后自动 ...

  8. Java Collection集合中的iterator方法

    Iterator接口的概述 /** * java.util.Iterator接口:选代器(对集合进行遍历) * 有两个常用的方法 * boolean hasNext() * 如果仍有元素可以迭代,则返 ...

  9. js 极简获取表单 元素 !

    let s =[]; $.each($('#formSearch input'),(m,n)=>{s.push(n)}); //示例获取表单所有 input 下滑线分割的 name 集合.set ...

  10. swagger生成错误问题 汇总解决

    Unable to render this definition The provided definition does not specify a valid version field. Ple ...