题意:

一个长度为N的整数序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,第K大的数是多少。

分析:

  仅仅就是一道整体二分的入门题而已,没听说过整体二分?

  其实就是一个分治的函数,但是呢,我所理解的,这是一个只分不治的过程。为什么?因为我们把数值域和操作域经过若干次划分划到最后,当数值域固定到一个值时,如果存在对应的操作域(此时应该是询问域)的结果就已经是这个值了,所以并不需要合并(治)。

  上面这段话可能被我复杂化了?那我们简单说。(以下是求区间第k小的步骤)

  这样的题一般都是给出一个序列,询问区间第k大/小。我们把这个序列看做添加一个数 a[i] 在位置 i 的操作。询问也是操作。

  然后就是一个递归函数,不断二分数值的范围(数值域),每次将属于 [ l,mid ] 这个范围的添加操作以原位置在树状数组中加1,直接划到左部(操作域),将 [ mid+1,r ]  直接划到右部(不碰树状数组),对于询问呢,假如在树状数组中查询到的,位于这个区间内的1的个数小于k,证明这个区间内,左部添加的数(不大于mid的)小于k个,所以这个询问的答案一定在右部添加的数中(也就是一定比mid要大),因此,假如这个区间内的数在左部有x个,我们需要在右部求出这个区间的第k-x小的数即可,即将次询问的k减去x,划分到右部,反之,若我们在树状数组上查出来的数大于等于k,证明答案会在左部被求出,直接划分到左部即可!

  我们无意间就维护了两个单调性,一个是加入顺序的单调性,另一个是数值的单调性,这二者的有机结合,恰好就是整体二分的优势,可以让其解决很多比较复杂,多处有二分性的题目。

  上面的解释可能大家看了都会很迷茫,但是研究代码会让你更明白。

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f,MAXN=;
struct node{
int x,y,z,id,type;
}a[MAXN],al[MAXN],ar[MAXN];
int n,m,ans[MAXN];
struct bit{
int a[MAXN];
void add(int x,int y)
{for(;x<=n;x+=x&(-x)) a[x]+=y;}
int query(int x){
int ans=;for(;x;x-=x&(-x)) ans+=a[x];
return ans;}
}t;
void solve(int l,int r,int ql,int qr){
if(ql>qr||l>r) return ;//l和r是数值域
if(l==r){//ql,lr是操作域
for(int i=ql;i<=qr;i++)
ans[a[i].id]=l;return ;
} int mid=(l+r)>>,lal=,lar=;
for(int i=ql;i<=qr;i++)
if(a[i].type){
if(a[i].y<=mid){
t.add(a[i].x,a[i].z);
al[++lal]=a[i];
} else ar[++lar]=a[i];
} else{ int tmp;
tmp=t.query(a[i].y)-t.query(a[i].x-);
if(tmp>=a[i].z) al[++lal]=a[i];
else ar[++lar]=a[i],ar[lar].z-=tmp;
} for(int i=;i<=lal;i++)
if(al[i].type==) t.add(al[i].x,-al[i].z);
for(int i=,j=ql;i<=lal;i++,j++)
a[j]=al[i];
for(int i=,j=ql+lal;i<=lar;i++,j++)
a[j]=ar[i];solve(l,mid,ql,ql+lal-);
solve(mid+,r,ql+lal,qr);return ;
} int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i].y),a[i].x=i,a[i].y=-a[i].y,
a[i].z=,a[i].type=;
scanf("%d",&m);
for(int i=,j=n+;i<=m;i++,j++)
scanf("%d%d%d",&a[j].x,&a[j].y,&a[j].z),a[j].x++,a[j].y++,
a[j].id=i,a[j].type=;
solve(-inf,inf,,n+m);
for(int i=;i<=m;i++)
printf("%d\n",-ans[i]); return ;
}

整体二分

  

51nod 1175 区间第k大 整体二分的更多相关文章

  1. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  2. POJ2104 K-th Number —— 区间第k小 整体二分

    题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Tota ...

  3. 静态区间第k小 - 整体二分

    蒟蒻终于学会整体二分啦! 思路 实现 丑陋无比的代码 #include <bits/stdc++.h> using namespace std; const int N = 200005; ...

  4. 【ZOJ2112】【整体二分+树状数组】带修改区间第k大

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  5. ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...

  6. Dynamic Rankings——带修改区间第k大

    三种做法:1.整体二分: 二分mid 考虑小于mid的修改的影响 但是大于mid的修改可能会干掉小于mid的一些值 所以额外把一个修改变成一个值的删除和一个值的添加 这样就相互独立了! 整体二分,树状 ...

  7. 解决区间第K大的问题的各种方法

    例题:http://poj.org/problem?id=2104 最近可能是念念不忘,必有回响吧,总是看到区间第k大的问题,第一次看到是在知乎上有人面试被弄懵了后来又多次在比赛中看到.以前大概是知道 ...

  8. Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)

    Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...

  9. 静态区间第k大(归并树)

    POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...

随机推荐

  1. SDK介绍

    软件开发工具包(外语首字母缩写:SDK.外语全称:Software Development Kit)一般都是一些软件工程师为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件时的开发工具的集合. ...

  2. bzoj 1306: [CQOI2009]match循环赛【dfs+剪枝】

    大力剪枝,最后洛谷上还开了o2才过-- 大概这样剪枝: 1.搜索中,一个队当前得分超过要求或者一个队剩下的比赛场数全赢也达不到要求则return: 2.注意到如果平局,最总分的贡献是2,否则是3,所以 ...

  3. bzoj 2006: [NOI2010]超级钢琴【st表+堆】

    设计一个五元组(i,l,r,p,v),表示在以i为左端点,右端点落在(l,r)中的情况下,取最大值v时右端点落在p.把这个五元组塞到优先队列里,以v排序,每次取出一个,然后把这个取过的五元组分成两个( ...

  4. ionic2 如何引入第三方cordova插件

    例如:cordova-plugin-wechat 这个插件可以做微信登录,分享支付等 首先第一步:ionic plugin add cordova-plugin-wechat --variable w ...

  5. Word Cloud (词云) - Matlab

    今天要总结的是 Word Cloud 最后一个部分了,用 Matlab 来创建 word cloud.Matlab R2018b 已经提供 wordcloud 函数可以直接生成词云了. >> ...

  6. JAVA值传递和引用传递 以及 实参是否改变

    八大数据类型和String 在进行传递的时候  不会改变. 八大数据类型 public class parameterValue { //值传递 public static void main(Str ...

  7. 给Ambari集群里安装可视化分析利器工具Hue步骤(图文详解)

    扩展博客 以下,是我在手动的CDH版本平台下,安装Hue. CDH版本大数据集群下搭建Hue(hadoop-2.6.0-cdh5.5.4.gz + hue-3.9.0-cdh5.5.4.tar.gz) ...

  8. 题解报告:hdu 1098 Ignatius's puzzle

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1098 题目中文是这样的: 伊格内修斯在数学上很差,他遇到了一个难题,所以他别无选择,只能上诉埃迪. 这 ...

  9. 加密解密(4)SSL协议及HTTPS握手过程

    SSL协议 简介 SSL (Secure Sockets Layer 安全套接层)是一个安全协议,它提供使用 TCP/IP 的通信应用程序间的隐私与完整性.因特网的 超文本传输协议 (HTTP)使用 ...

  10. Python 设计模式--简单工厂模式

    简单工厂模式(Factory Pattern)是一种创建型的设计模式,像工厂一样根据要求生产对象实例. 特点:根据不同的条件,工厂实例化出合适的对象. <大话设计模式>中实例:四则运算计算 ...