【算法学习】整体二分

我们开门见山,讲讲一道sb题:

给你一个数组,查这个数组的第x大元素。

排序?可以

二分?怎么做啊?

二分出一个mid,判断这个数组中有多少个数小于等于mid,如果个数大于等于x,就递归到[l,mid]区间,否则是[mid+1,r]区间,这样递归下去就能得到结果。

怎么计算小于等于mid的个数?

for一遍原数组?其实只要存储数组中值在[l,r]中的数,然后计算就好,而对于[1,l-1],可以预先存储。

怎么计算?树状数组,范围太大就离散化。

这样很麻烦吧?排序更好吧?

但是当我给你多个询问时,你就不会这么觉得了。

回顾刚才的过程,我们做上图的类比。

把询问看成球,答案的区间就是这个矩形,每一次我们将上一层的球判断它会掉到下层的哪一块中,掉到底层就是获得了答案。

刚刚的过程就是球只有1个的情况。

球有多个时,就是整体二分!

就是对于当前的mid,对每一个询问都计算答案是大了还是小了,然后决定分配到下一层的哪边。

要注意保证时间复杂度哦!

一道例题:HDU 5412。

查询区间K小,要支持单点修改。

看代码:

 1 #include<cstdio>
 2 int n,q,a[100001],sum[300001],ans[300001],que1[300001],que2[300001],bit[300001];
 3 int I[300001],type[300001],ql[300001],qr[300001],k[300001],cnt;
 4 inline void ins(int t,int l,int r,int x){type[++cnt]=t,ql[cnt]=l,qr[cnt]=r,k[cnt]=x,I[cnt]=cnt;}
 5 inline void Ins(int i,int x){for(;i<=n;bit[i]+=x,i+=i&-i);}
 6 inline int Qur(int i){int Sum=0;for(;i;Sum+=bit[i],i-=i&-i);return Sum;}
 7 void divide(int l,int r,int low,int upp){
 8     if(l>r) return;
 9     if(low==upp) {for(int i=l;i<=r;++i) if(type[I[i]]==3) ans[I[i]]=low; return;}
10     int mid=low+upp>>1,cl=0,cr=0;
11     for(int i_=l,i;i_<=r;++i_){
12         i=I[i_];
13         if(type[i]==1) {if(k[i]<=mid) Ins(ql[i],1), que1[++cl]=i; else que2[++cr]=i;}
14         if(type[i]==2) {if(k[i]<=mid) Ins(ql[i],-1), que1[++cl]=i; else que2[++cr]=i;}
15         if(type[i]==3){
16             int tmp=Qur(qr[i])-Qur(ql[i]-1);
17             if(k[i]<=sum[i]+tmp) que1[++cl]=i;
18             else que2[++cr]=i, sum[i]+=tmp;
19         }
20     }
21     for(int i_=l,i;i_<=r;++i_){
22         i=I[i_];
23         if(type[i]==1) if(k[i]<=mid) Ins(ql[i],-1);
24         if(type[i]==2) if(k[i]<=mid) Ins(ql[i],1);
25     }
26     for(int i=1;i<=cl;++i) I[l+i-1]=que1[i];
27     for(int i=1;i<=cr;++i) I[l+cl+i-1]=que2[i];
28     divide(l,l+cl-1,low,mid); divide(l+cl,r,mid+1,upp);
29 }
30 int main(){
31     scanf("%d",&n);
32     for(int i=1;i<=n;++i) scanf("%d",a+i), ins(1,i,i,a[i]);
33     scanf("%d",&q);
34     for(int i=1,t,x,y,z;i<=q;++i){
35         scanf("%d",&t);
36         if(t==1) scanf("%d%d",&x,&y), ins(2,x,x,a[x]), ins(1,x,x,y), a[x]=y;
37         else scanf("%d%d%d",&x,&y,&z), ins(3,x,y,z);
38     }
39     divide(1,cnt,1,1000000000);
40     for(int i=1;i<=cnt;++i) if(ans[i]) printf("%d\n",ans[i]);
41     return 0;
42 }
View Code

一道例题:洛谷 P3332。

查询区间K大,要支持区间加入。

看代码:

 1 #include <cstdio>
 2 
 3 typedef long long LL;
 4 const int MN = 50005;
 5 
 6 int N, Q;
 7 
 8 int opt[MN], L[MN], R[MN]; LL V[MN];
 9 int P[MN];
10 int s1[MN], s2[MN], t1, t2;
11 
12 LL Sum[MN];
13 int Ans[MN];
14 
15 LL b1[MN], b2[MN];
16 inline void Add(LL *b, int i, LL x) { for(; i <= N; i += i & -i) b[i] += x; }
17 inline LL Qur(LL *b, int i) { LL A = 0; for(; i; i -= i & -i) A += b[i]; return A; }
18 inline void Add(int l, int r, LL x) {
19     ++r;
20     Add(b1, l,  x), Add(b2, l,  (l - 1) * x);
21     Add(b1, r, -x), Add(b2, r, -(r - 1) * x);
22 }
23 inline LL Qur(int l, int r) {
24     --l;
25     return r * Qur(b1, r) - Qur(b2, r) - l * Qur(b1, l) + Qur(b2, l);
26 }
27 
28 void Solve(int l, int r, int lb, int rb) {
29     if (lb == rb) {
30         for (int i = l; i <= r; ++i)
31             if (opt[P[i]] == 2)
32                 Ans[P[i]] = lb;
33         return ;
34     }
35     int mid = lb + rb >> 1;
36     t1 = t2 = 0;
37     for (int i = l; i <= r; ++i) {
38         if (opt[P[i]] == 1) {
39             if (V[P[i]] <= mid)
40                 s1[++t1] = P[i];
41             else {
42                 Add(L[P[i]], R[P[i]], 1);
43                 s2[++t2] = P[i];
44             }
45         }
46         else {
47             LL num = Sum[P[i]] + Qur(L[P[i]], R[P[i]]);
48             if (num >= V[P[i]]) 
49                 s2[++t2] = P[i];
50             else {
51                 Sum[P[i]] = num;
52                 s1[++t1] = P[i];
53             }
54         }
55     }
56     for (int i = l; i <= r; ++i) {
57         if (opt[P[i]] == 2) continue;
58         if (V[P[i]] > mid)
59             Add(L[P[i]], R[P[i]], -1);
60     }
61     int pos = l;
62     for (int i = 1; i <= t1; ++i)
63         P[pos++] = s1[i];
64     for (int i = 1; i <= t2; ++i)
65         P[pos++] = s2[i];
66     int M = l + t1 - 1;
67     Solve(l, M, lb, mid);
68     Solve(M + 1, r, mid + 1, rb);
69 }
70 
71 int main() {
72     scanf("%d%d", &N, &Q);
73     for (int i = 1; i <= Q; ++i) {
74         scanf("%d%d%d%lld", opt + i, L + i, R + i, V + i);
75         P[i] = i;
76     }
77     Solve(1, Q, -N, N);
78     for (int i = 1; i <= Q; ++i) {
79         if (opt[i] == 1) continue;
80         printf("%d\n", Ans[i]);
81     }
82     return 0;
83 }
View Code

 

转载于:https://www.cnblogs.com/PinkRabbit/p/8039083.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql leave的作用_MySQL数据库中DELIMITER的作用

以下的文章主要是向大家描述的是MySQL数据库中delimiter的作用是什么?我们一般都认为这个命令和存储过程关系不大&#xff0c;到底是不是这样的呢&#xff1f;以下的文章将会给你相关的知识&#xff0c;望你会有所收获。下面是一个存储过程的实例&#xff1a;DELIMITER $$USE …

Fullpage参数说明

参数说明 $(document).ready(function() {$(#fullpage).fullpage({//Navigationmenu: false,//绑定菜单&#xff0c;设定的相关属性与anchors的值对应后&#xff0c;菜单可以控制滚动&#xff0c;默认为false。anchors:[firstPage, secondPage],//anchors定义锚链接&#xff0c…

mysql100个优化技巧_完整篇:100+个MySQL调试和优化技巧(2)

▼MySQL模式优化51.检查和经常优化表.52. 经常重写InnoDB表优化.53. 有时&#xff0c;当添加列时删除索引&#xff0c;然后在添加回来索引&#xff0c;这样就会更快.54. 针对不同的需求&#xff0c;使用不同的存储引擎.55. 使用归档存储引擎日志表或审计表-这是更有效地写道.56…

Java Swing

编辑中... 转载于:https://www.cnblogs.com/startup-try/p/8040625.html

包装类java_Java 包装类

也叫过滤流类处理刘类没有对应到任何具体的流设备&#xff0c;需要给它传递一个对应的具体流设备的输出/输入流对象I/0内存缓冲BufferedInputStream,BufferedOutputStream 缓冲区包装类 默认32个字节缓冲区的缓冲流内存/磁盘扇区一次读写操作所能完成最大字节数的整数倍(4的整数…

简单的SQL注入学习

引贴&#xff1a; http://blog.163.com/lucia_gagaga/blog/static/26476801920168184648754/ 首先需要编写一个php页面&#xff0c;讲php页面放入/opt/lampp/htdocs目录下&#xff1a; 解释一下这个页面&#xff1a; 1.通过if语句判断变量是否初始化 2.if语句中通过mysql_conne…

vb红绿灯自动切换_VB红绿灯程序

《VB红绿灯程序》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《VB红绿灯程序(4页珍藏版)》请在人人文库网上搜索。1、VB红绿灯演示Private Sub Command1_Click()While (1)Shape1.FillColor RGB(255, 0, 0)Shape2.FillColor RGB(0, 0, 0)Shape3.FillColor RGB(0, …

什么是网站监控?

网站监控是跟踪网站的可用性和性能&#xff0c;以最小化宕机时间&#xff0c;优化性能并确保顺畅的用户体验。维护网站正常运行对于任何企业来说都是至关重要的&#xff0c;因而对大多数业务来说&#xff0c;网站应用监控都是一个严峻的挑战。Applications Manager网站应用监控…

循序渐进PYTHON3(十三) --4-- DJANGO之CSRF使用

用 django 有多久&#xff0c;跟 csrf 这个概念打交道就有久。 每次初始化一个项目时都能看到 django.middleware.csrf.CsrfViewMiddleware 这个中间件每次在模板里写 form 时都知道要加一个 {% csrf_token %} tag每次发 ajax POST 请求&#xff0c;都需要加一个 X_CSRFTOKEN 的…

java string replace 重载_关于Java:如何使用replace(char,char)替换字符b的所有实例为空...

如何使用replace(char&#xff0c;char)将字符" b"的所有实例全部替换为空。例如&#xff1a;Hambbburger to Hamurger编辑&#xff1a;有一个约束&#xff0c;我只能使用1.4.2&#xff0c;这意味着没有重载版本的replace&#xff01;你不能因为什么都不是字符&#…

JavaScript——执行环境、变量对象、作用域链

前言 这几天在看《javascript高级程序设计》&#xff0c;看到执行环境和作用域链的时候&#xff0c;就有些模糊了。书中还是讲的不够具体。通过上网查资料&#xff0c;特来总结&#xff0c;以备回顾和修正。 目录&#xff1a; EC(执行环境或者执行上下文&#xff0c;Execution …

java线程interrupt用法_Java 如何中断线程

本篇文章帮大家学习java 如何中断线程&#xff0c;包含了Java 如何中断线程使用方法、操作技巧、实例演示和注意事项&#xff0c;有一定的学习价值&#xff0c;大家可以用来参考。以下实例演示了如何使用interrupt()方法来中断线程并使用 isInterrupted() 方法来判断线程是否已…

laravel5.4之artisan使用总结一

Artisan是laravel自带的命令行接口&#xff1a; php artisan list 编写命令 生成命令&#xff1a; 可以使用Artisan命令&#xff0c;php artisan make:command ConsoleTest 执行完这个命令后&#xff0c;会在app/Console/Commands 目录下创建ConsoleTest命令类。会包含默认的属…

java如何保证类不被回收_垃圾回收机制保证了Java程序不会出现内存溢出。( )

【简答题】1.激素(名词解释)【单选题】6.下列哪种情况下可引起ADH分泌增加【判断题】在Java中使用String类型的实例对象表示一个字符串。( )【判断题】static关键字可以修饰成员变量,也可以修饰局部变量。( )【单选题】建设项目投资控制应贯穿于建设工程全过程,在建设项目实施阶…

intellij idea 分屏设置 与快捷键

1、找到分屏功能 File -> setting -> keymap&#xff0c;搜索&#xff08;注意大小写&#xff09;&#xff1a;   Split Vertically 水平分屏   Split Horizontally 垂直分屏 2、设置快捷键&#xff0c; 编辑快捷键的地方在搜索框同一行&#xff1a;    在标签上直…

java parseexception_Java ParseException类代码示例

import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException; //导入依赖的package包/类Overridepublic void read(File file) throws IOException {try {Document doc db.parse(file);NodeList nlTimeSlots (NodeList) xp.evaluate("/ANNOTATION_DOCU…

bzoj 4016: [FJOI2014]最短路径树问题

Description 给一个包含n个点&#xff0c;m条边的无向连通图。从顶点1出发&#xff0c;往其余所有点分别走一次并返回。 往某一个点走时&#xff0c;选择总长度最短的路径走。若有多条长度最短的路径&#xff0c;则选择经过的顶点序列字典序最小的那条路径(如路径A为1,32,11&am…

java.nio.file 找不到_java - 断言该错误:无法访问路径(找不到java.nio.file.Path) - 堆栈内存溢出...

我想使用Robolectric进行单元测试&#xff0c;但是我正在尝试使用robolectric进行简单测试&#xff0c;因此一开始我很困惑。 我遵循了手册&#xff0c;对示例进行了同样的操作&#xff0c;甚至其他帖子也无济于事。 每次收到错误消息&#xff1a;无法访问路径。 找不到java.ni…

SSH整合方案二(不带hibernate.cfg.xml)

整体结构: 1.引入相关jar包 2.编写实体类和映射文件 package cn.zqr.domain;public class Customer {private Long cust_id;private String cust_name;private Long cust_user_id;private Long cust_create_id;private String cust_source;private String cust_industry;privat…

java铃声类_MediaPlayer.setDataSource中的java.lang.IllegalStateException,使用铃声类

我有一个用户(Samsung Galaxy S5&#xff0c;Android 4.4)报告的崩溃&#xff0c;我不明白发生了什么。这似乎是可以吸收的&#xff0c;但也许有些人遇到了同样的问题&#xff0c;或类似的问题。MediaPlayer.setDataSource中的java.lang.IllegalStateException&#xff0c;使用…