首页 > 其他分享 >[OI] 整体二分

[OI] 整体二分

时间:2024-09-03 21:47:57浏览次数:10  
标签:二分 OI int 询问 整体 mid 区间

整体二分可以理解成普通二分改版,其实并没有改多少,并且一般对 check() 函数的复杂度要求更宽松

先来看一道经典题目:求区间排名

给一个数列,若干组询问 \((l,r,k)\),求 \([l,r]\) 内第 \(k\) 大,询问次数较大

注意到询问次数较大,因此需要整体二分来解决

首先考虑普通二分,很容易想到一个比较暴力的想法:对值域二分,每次暴力遍历一遍 \([l,r]\),把大于 \(mid\) 的都挑出来,假如个数比 \(k\) 多则二分左区间,否则二分右区间

这是一种比较无脑的 \(n\log n\) 二分方法,现在我们来尝试把它改造成整体二分:

首先定义一个求解范围 \([L,R]\),表示我们现在正在求解编号 \([L,R]\) 范围内的询问,初始的时候令这个范围为 \([1,q]\)

然后,我们进行正常二分,此时应该枚举 \(mid=\frac{n}{2}\)

还是按照上面的办法,暴力遍历一遍 \([l,r]\),把大于 \(mid\) 的都挑出来

然后我们可以确定出每一个询问区间里大于 \(mid\) 的数有多少个,对于此题来说,只需要求一遍前缀和即可进行维护

此时会发现询问分为了两类:一类是区间内大于 \(mid\) 的数比询问的 \(k\) 更多,另一类反之

因此我们可以直接给询问重新排序,将它们分成两拨,一类都在左边,一类都在右边

容易发现,左边的询问只需要二分 \([l,mid]\) 即可,而右边的询问仅需要二分 \([mid+1,r]\) 即可,这样便可以缩减复杂度

void check(int l,int r,int L,int R){
    //[l,r] 为值域区间, [L,R] 为询问区间
    if(l==r){
        //二分结束,统计答案
        for(int i=L;i<=R;++i){
            ans[q[i].id]=l;
        }
        return;
    }
    int mid=(l+r)/2;
    for(int i=1;i<=n;++i){
        sum[i]=sum[i-1]+(a[i]<=mid);
    }
    int cnt1=0,cnt2=0;
    //lst1,lst2 分别统计两类询问的编号,cnt1/2 是给这两个数组计数用的
    //注意这两个 cnt1/2 一定要开成局部变量!!!否则会因为递归修改了值导致直接炸掉
    for(int i=1;i<=Q;++i){
        int res=sum[q[i].r]-sum[q[i].l-1];
        if(res<=q[i].k){
            lst1[++cnt1]=i;
        }
        else{
            lst2[++cnt2]=i;
        }
    }
    //按顺序合并询问
    int now=L-1;
    for(int i=1;i<=cnt1;++i){
        id[++now]=lst1[i];
    }
    for(int i=1;i<=cnt2;++i){
        id[++now]=lst2[i];
    }
    //继续二分
    check(l,mid,L,L+cnt1-1);
    check(mid+1,r,L+cnt1,R);
}

相似的问题可以去看 P1527,是一道二维的区间排名问题,因此处理的时候不能再只使用前缀和了

以及 P3527,这是一道一维的带修问题,不过它求的不是排名,所以也异曲同工了

一维带修排名问题也可以整体二分,详见 P3332

标签:二分,OI,int,询问,整体,mid,区间
From: https://www.cnblogs.com/HaneDaCafe/p/18395475

相关文章

  • BroadcastReceiver 广播-Android四大组件 一文精讲
    目录1.广播用途与机制1.1什么时候用broadcast?1.2原理图解2.注册广播2.1静态注册2.2动态注册2.3二者区别与联系同:异:3.接受广播3.1接收系统广播3.2接收自定义附带值广播4.发送自定义广播4.1发送无序广播4.2发送有序广播4.3发送应用程序内部广播1.广播用途与......
  • 8.31 下午 梦熊联盟 NOIP 模拟赛总结 & 题解
    T1北极星一个比较好想到的点是从后往前枚举数,计算得出它需要的操作次数,然后给所有前面的数都加上这个操作次数,这样就把每个数独立出来了。所以这道题就变成了如何快速通过这些操作得到一个指定的数。观察大样例的输出,发现每一个数都是11?1?1?的形式,其中问号为+或c,我们可......
  • 一文迅速上手 ESP32 bluedroid 蓝牙从机开发
    前言该博客主要针对希望迅速上手ESP32蓝牙从机开发人员,因此,很多蓝牙技术细节知识并不会进行介绍,仅仅介绍我认为需要了解的API函数和回调内容。本文主要是基于gatt_serverdemo来微调进行进行讲解。代码#include<stdio.h>#include<stdlib.h>#include<string.h>#include<i......
  • DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection
    AbstractWepresentDINO(DETRwithImproveddeNoisinganchOrboxes),astate-of-the-artend-to-endobjectdetector.DINOimprovesoverpreviousDETR-likemodelsinperformanceandefficiencybyusingacontrastivewayfordenoisingtraining,amixedqu......
  • 前端Vue项目iHRM人力资源后台管理从Vue模板到整体开发Nginx部署上线
    前端Vue项目iHRM人力资源后台管理:‌从Vue模板到整体开发Nginx部署上线引言随着企业信息化的不断深入,‌人力资源管理系统的自动化和智能化成为企业提升管理效率的重要手段。‌本文将详细介绍一个基于Vue.js开发的人力资源后台管理系统(‌iHRM)‌的完整开发流程,‌包括从Vue模板的选......
  • Deploy Sharepoint项目的wsp包之后调用出现缺失DLL的错误
    server:Windowsserver2022datacenter.Sharepoint:SE.使用VS2022deploy之后,web页面访问SharePoint站点报缺失DLL的错误,这里边引入了NPOI库用来导入导出excel,但是导入的时候某些excel就会报错System.IO.FileNotFoundException:Couldnotloadfileorassembly'System.......
  • Android开发 - BitmapFactory 类解码图像文件并转换为 Bitmap 对象与 BitmapFactory.O
    BitmapFactory是什么BitmapFactory用于解码图像文件,并将它们转换为Bitmap对象。Bitmap是用来表示图像的基本类,它是一个位图的抽象表示。BitmapFactory提供了一组静态方法,这些方法可以用来将各种图像文件格式(如PNG、JPEG、WEBP等)解码成Bitmap对象BitmapFactory的好......
  • Jenkins启动报错java.lang.NullPointerException
    centos6.9下安装Jenkins,可以正常安装,但是启动后,Jenkins.log中发现报错java.lang.NullPointerException:Cannotloadfromshortarraybecause"sun.awt.FontConfiguration.head"isnullatjava.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:......
  • Android经典实战之窗口和WindowManager
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在Android开发中,“窗口”是一个非常基础且重要的概念。窗口通常用于承载和显示用户界面内容。了解窗口的工作机制,以及如何管理窗口,对于开发复杂的和用户体验良好的应用程序至......
  • Android Activity启动过程全解析
     https://blog.csdn.net/tenggangren/article/details/50925740 App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。一个App的程序入口到底是什么?是ActivityThread.main()。 1.ActivityManagerServices,简称AMS,服务端对象,负责系统中所有A......