首先说明这篇博客写得奇差无比

  让我们理清一下为什么要打分块,在大部分情况下,线段树啊,splay,treap,主席树什么的都要比分块的效率高得多,但是在出问题的时候如果你和这些数据结构只是混的脸熟的话,一旦错误可能就会导致心态崩溃,而且调试困难(大佬:很轻松啊....)所以,分块是一个时间效率不是很高的,代码量也不是很高的数据结构,水分是可以的,在全场都是30分的情况下,你能用分块水到个60,70就是胜利,所以分块很多时候也是和STL一起用的,达到(nlogn√n)的效果吧。


  原理

    把一段数列1...n分成√n块,如果√n*√n<n,n++。这样能保证每一块的大小都<=√n,我不会证明,但是此时时间复杂度一般为(n√n),就可以开始水分了。

    比如,在我们要解决一段100000左右的序列时,最简单的询问 (l,r)求和 给(l,r)加上一个值。

    大佬A:线段树@#@@¥%@!#(啪)

    大佬B:平衡树%¥……¥#%@@(啪)

    大佬C:树套树@¥%@#%#……(啪)

    那么身为蒟蒻的我:分块!(瑟瑟发抖)

    

    首先让我们来讲一讲分块是什么

    分块,我这里只是简单的把一段数,放到几个块里面,怎么放呢,按照某个大佬的证明,把每连续的√n个数放在一个块里的时间复杂度一般是最优的,当然有时候√n并不是最优解。

    

    那么要怎么分呢?

    首先,我们让int tmp=sqrt(n),这样就可以保证有√n块,然后如果有任何一块处于(l,r)之间,就给这个块打上标记进行操作,这样肯定是有可能会有 l和r 处在两个块中的,而且我们也不能对那两的块直接修改,就暴力修改块里面的内容。即每一次的时间复杂度大概为(3√n)。

    所以我们就是要预先处理好每一块的内容,预处理大概是(n√n)的,查询大概是(1)的。

    大概的建块过程如下

void build()
{
num=tmp;if(tmp*tmp<n)num++; //因为int向下取整,所以有可能tmp*tmp<n,存不了那么多的数
for(int i=;i<=num;i++)
{
l[i]=num*(i-)+;r[i]=num*i; //每一个块的左右区间
}
r[num]=n;
int s= ;
for (int i=;i<=n;i++) {if (i>r[s]) s++; belong[i]=s;} //处理出每一个数所属于的块
//...
//你要预处理的内容
}

    然后查询跟上面也差不多,因题目而异。

    下面贴一个静态查询最大值的代码

    

int query(int x,int y)
{
int ans=-;
if(belong[x]==belong[y])//在一个块内就直接暴力统计
{
for(int i=x;i<=y;i++)
ans=max(ans,ch[i]);
return ans;
}
for(int i=x;i<=r[belong[x]];i++)//统计最左边的块的情况
ans=max(ans,ch[i]);
for(int i=belong[x]+;i<=belong[y]-;i++)//中间的先于预处理好,然后每一块的情况O(1)查询
ans=max(ans,maxx[i]);
for(int i=l[belong[y]];i<=y;i++)//统计最右边的块的情况
ans=max(ans,ch[i]);
return ans;
}

    所以原理大概就讲到这里吧。


  现在通过一些简单的例题入门吧。

  1.教主的魔法

  2.[HNOI2010]弹飞绵羊

  3.哈希冲突

  4.作诗  

  5.[Violet]蒲公英

  

  1.教主的魔法

  做法分析:

  分块+排序+二分

  首先我们把这个题目拆开来看:

  (1)要询问或给(l,r)加一个值

  (2)在(l,r)区间的值是不定值,还要求的是大于等于k的数有多少

  由(1)–>得尝试分块和分块的加法标记

  由(2)–>得我们可以事先处理好每一块的顺序,然后找到大于等于k的第一个数,就能求出每一块的贡献值了–>sort+vector

  要注意的是,当l,r处在两个不完整的块,暴力加上在排序就ok了

  祝大佬AC愉快23333333

  教主的魔法[分块+二分]

  

  2.弹飞绵羊

  做法分析:

  不属于hzw的入门分块练习

  这里需要我们处理出每一块中,进入某个点后,会进入下一个块的哪一个点,需要几次才能弹出块,修改时记得同时修改相应块的内容。

  靠大佬自己思维了。

  [HNOI2010]弹飞绵羊(分块)

  3.哈希冲突

  做法分析:

  (sqrt(),不只是分块)

  (1)首先,我们先处理出sqrt()内的模数池的值,这样询问就只要o(1),预处理o(n√n)。

  (2)其次,当模数大于sqrt()时,我们暴力一次的代价为o(√n)

  哈希冲突[分块(思想)]   

  

  4.作诗

  做法分析:

  1.我们考虑一下分块的话要每一块都保存是正偶数的数字的个数,用一个ans[i][j]保存第i块到第j块内符合条件的数字的个数,o(1)的查询,前缀和的思想

  2.在最左端的最右端的用一个统计数组暴力即可

  3.但是要记住最左端和最右端的数字要与整个[l,r]区间相关联,所以用一个sum[i][j]保存第[i]块第[j]种颜色的数量

  作诗(si)[分块]

  5.蒲公英

  做法分析:

  排序+离散化+二分+区间预处理+分块

  (1)读入的每一个值超过一个数组下标可以统计的范围–>离散化

  (2)求众数==教主的魔法(2)的思想–>sort+vector

  (3)为了更加优化时间复杂度,我们事先处理好[l,r]里面经过块的众数,然后暴力vector不完整块的中可能的众数–>区间预处理

  分块qwq蒟蒻我已经没什么能教的了,大佬AK比赛愉快。

  蒲公英[分块]

   ps:(最后推荐一下黄学长的分块,大概是所有分块里面教的最好的了)「分块」数列分块入门1 – 9 by hzwer

浅析[分块]qwq的更多相关文章

  1. [Libre 6281] 数列分块入门 5 (分块)

    水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...

  2. 「国家集训队」Crash的数字表格

    题目描述 求(对 \(20101009\) 取模,\(n,m\le10^7\) ) \[\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)\] 大体思路 推 ...

  3. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  4. 洛谷3203 弹飞绵羊(LCT)

    据说这个题当年的正解是分块qwq 根据题目所说,对于题目中的弹力系数,就相当于一条边,那么对于"跳出去"这个限制,我们可以选择建造一个新点\(n+1\)表示结束,那么每次,求一个点 ...

  5. 分块学习笔记qwq

    我没想到居然就学到分块了...哇我还一直觉得分块听起来挺牛逼的一直想学的来着qwq(其实之前好像vjudge上有道题是用分块做的?等下放链接qwq 所以想着就写个学习笔记趴qwq 首先知道分块的时间复 ...

  6. 【tyvj1463】智商问题 [分块][二分查找]

    Background 各种数据结构帝~各种小姊妹帝~各种一遍AC帝~ 来吧! Description 某个同学又有很多小姊妹了他喜欢聪明的小姊妹 所以经常用神奇的函数来估算小姊妹的智商他得出了自己所有 ...

  7. CH#46 磁力块 分块

    正解:分块+bfs 解题报告: 先放个传送门,然后瞎扯淡下QAQ 突然感觉不停课大概是正确的选择QAQ 大概实在是没有天赋?明明都知道正解是分块甚至还听了下解法感觉理解了,再看一次依然没想到解法,,, ...

  8. CFGym101138D Strange Queries 莫队/分块

    正解:莫队/分块 解题报告: 传送门 ummm这题耗了我一天差不多然后我到现在还没做完:D 而同机房的大佬用了一个小时没有就切了?大概这就是大佬和弱鸡的差距趴QAQ 然后只是大概写下思想好了因为代码我 ...

  9. 洛谷P3455 ZAP-Queries [POI2007] 莫比乌斯反演+数论分块

    正解:莫比乌斯反演 解题报告: 传送门! 首先这题刚看到就很,莫比乌斯反演嘛,和我前面写了题解的那个一模一样的,所以这儿就不讲这前边的做法辣QAQ 但是这样儿还有个问题,就现在已知我每次都是要O(n) ...

随机推荐

  1. 51nod 1098 最小方差 排序+前缀和+期望方差公式

    题目: 题目要我们,在m个数中,选取n个数,求出这n个数的方差,求方差的最小值. 1.我们知道,方差是描述稳定程度的,所以肯定是着n个数越密集,方差越小. 所以我们给这m个数排个序,从连续的n个数中找 ...

  2. SLAM概念学习之随机SLAM算法

    这一节,在熟悉了Featue maps相关概念之后,我们将开始学习基于EKF的特征图SLAM算法. 1. 机器人,图和增强的状态向量 随机SLAM算法一般存储机器人位姿和图中的地标在单个状态向量中,然 ...

  3. c#0218-命名空间

    1 namespace 命名空间 可以解决类的重命名问题 可以看做是类的文件夹: 2 跨项目使用类 一个解决方案下有不同的项目,如果想在一个项目中引用另一个项目的类,解决方法是 1 添加引用 2 引用 ...

  4. POJ 2155 Matrix【 二维树状数组 】

    题意:给出两种操作,C是给出一个矩形的左上角和左下角的下标,把这个矩形里面的0变成1,1变成0,Q是询问某个点的值 看这篇论文讲得很清楚 http://wenku.baidu.com/view/1e5 ...

  5. eclipse的maven工程视图切换

    上面图切换成下面图: 点击eclipse右上角,如下图红圈,然后在选择javaEE这样就切换成javaEE视图了

  6. ZOJ 2702 Unrhymable Rhymes

    Unrhymable Rhymes Time Limit:10000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu De ...

  7. 洛谷 P1033 自由落体

    P1033 自由落体 题目描述 在高为 H 的天花板上有 n 个小球,体积不计,位置分别为 0,1,2,….n-1.在地面上有一个小车(长为 L,高为 K,距原点距离为 S1).已知小球下落距离计算公 ...

  8. [ML] Daily Portfolio Statistics

    Let's you have $10000, and you inverst 4 stocks. ['SPY', 'IBM', 'XOM', 'GOOG']. The allocation is [0 ...

  9. 一个使用sbt编译的JNI C++ 的模板

    假设你须要在Scala或是Java中调用C或C++函数库,就须要使用JNI. 这里就涉及到编译scala ,java 和C(C++)代码,在这里给出一个程序的框架,我们使用sbt 缺省的代码文件夹 文 ...

  10. 使用quick自己定义Button

    使用quick时自己封装的类存放于特定的文件夹.便于以后使用 以下是作者经经常使用到的一个按钮 local MyButton = class("MyButton") functio ...