分块算法在学习之前一直觉得是一个高端大气上档次,有着与众不同的O(√N)的时间复杂度。

(打公式真是太烦了,不过如果我不打公式zichen0535巨佬肯定又要嘲讽我。。。)

直到我阅读多方博客,才发现,这tm就是一个流氓算法。

对于区间问题,

我们把要处理的所有元素从左到右分成M个等长区间(以下称“块”)和最后一个比正常块略小的块,那么显然除了最后一个区间,每个区间的长度都是,最后一个区间长度是N%M。

可以证明M等于√N的时候,时间复杂度最低,这个分析完原理后再证明。

需要维护的信息有:

belong[x]:元素x所在的块的编号,样例代码中为bl[x];

start[x]:编号为x的块的最左边的点,样例代码中为st[x];

end[x]:编号为x的块的最右边的点,样例代码中为ed[x];

我们处理一个l到r的操作的时候,分类讨论一下

如果l和r在一个块中或者l和r在相邻块中,那么直接从l到r暴力处理一遍,处理的次数一定小于块的大小,也就是M。

如果l所在的块和r所在的块中间还有其它块,那么我们先暴力处理l到l所在块的右端,然后暴力处理r所在区间的左端到r,处理次数小于2*M。然后处理中间的块,因为块的处理非常方便,可以另外建立数组维护块的变化信息(如加上某个值),所以我们每个块只需要处理一次,那么我们处理次数少于次。

所以我们的复杂度分析就是O(M+)。根据基本不等式( )可知,在M=时取得最小值√N。解得M=√N时取得最小值。

所以我们在解决一般的题目时都会把所有元素分成√N个区间。

那么对于Q个操作,最终时间复杂度就是O(Q√N)。

这里给一道例题(奇水)     传送门

附上我的代码(略丑)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 100005
using namespace std;
inline void read(int &x){x=0;int f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}x*=f;
}
inline void read(long long &x){x=0;int f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}x*=f;
}
int N,M,len,tot;
int st[maxn],ed[maxn],bl[maxn];
long long add[maxn],arr[maxn],sum[maxn];
void init()
{len=sqrt(N);tot=N/len;if(N%len)tot++;for(int i=1;i<=N;i++){bl[i]=(i-1)/len+1;sum[bl[i]]+=arr[i];}for(int i=1;i<=tot;i++){st[i]=(i-1)*len+1;ed[i]=i*len;}
}
void update(int l,int r,long long k)
{if(r<=ed[bl[l]]){for(int i=l;i<=r;i++){arr[i]+=k;sum[bl[i]]+=k;}return ;}for(int i=l;i<=ed[bl[l]];i++){arr[i]+=k;sum[bl[i]]+=k;}for(int i=bl[l]+1;i<bl[r];i++){sum[i]+=len*k;add[i]+=k;}for(int i=st[bl[r]];i<=r;i++){arr[i]+=k;sum[bl[i]]+=k;}
}
long long query(int l,int r)
{long long ans=0;if(r<=ed[bl[l]]){for(int i=l;i<=r;i++){ans+=arr[i];}return ans;}for(int i=l;i<=ed[bl[l]];i++)ans+=arr[i]+add[bl[i]];for(int i=bl[l]+1;i<bl[r];i++)ans+=sum[i];for(int i=st[bl[r]];i<=r;i++)ans+=arr[i]+add[bl[i]];return ans;
}
int main()
{read(N);read(M);for(int i=1;i<=N;i++)read(arr[i]);init();int op,l,r;long long k;while(M--){read(op);read(l);read(r);if(op==1){read(k);update(l,r,k);}else{printf("%lld\n",query(l,r));}    }
}

转载于:https://www.cnblogs.com/sherrlock/p/9594643.html

[算法笔记]分块算法从入门到TLE相关推荐

  1. 优化算法笔记|灰狼算法理解及Python实现

    灰狼优化算法的理解和应用 一.背景介绍 二.算法原理 三.构建算法数学模型 四.Python实现GWO 五.算法分析 一.背景介绍 灰狼优化算法(Grey Wolf Optimizer,GWO)由澳大 ...

  2. 算法笔记_070-BellmanFord算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为BellmanFord算法? BellmanFord算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶 ...

  3. 回溯 皇后 算法笔记_算法笔记_04_回溯

    设计思想: (1)适用:求解搜索问题和优化问题. (2)搜索空间:数,节点对应部分解向量,可行解在树叶上. (3)搜索过程:采用系统的方法隐含遍历搜索树. (4)搜索策略:深度优先,宽度优先,函数优先 ...

  4. 算法笔记_163:算法提高 最大乘积(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? 输入格式 第一行一个数表示数据组数 每组输入数据共2行: 第1行给出总共的数 ...

  5. 优化算法笔记|萤火虫算法理解及实现

    萤火虫算法 一.萤火虫算法背景知识 二.萤火虫算法 三.萤火虫算法实现 四.算法分析 一.萤火虫算法背景知识 萤火虫算法(Firefly Algorithm, FA)是基于萤火虫的闪光行为,它是一种用 ...

  6. 算法笔记--KMP算法 EXKMP算法

    1.KMP算法 这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html 模板: next数组的求解,那个循环本质就是如果相同前后缀不能加上该位 ...

  7. 算法笔记_167:算法提高 矩阵翻转(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 Ciel有一个N*N的矩阵,每个格子里都有一个整数. N是一个奇数,设X = (N+1)/2.Ciel每次都可以做这样的一次操作:他从矩阵 ...

  8. 算法笔记-排序算法(冒泡 选择 插入)

    首先罗列一下常见的十大排序算法: 一.冒泡排序 1. 定义: 冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则 ...

  9. 【算法笔记】算法的平均时间复杂度A(n)的公式及示例

    算法平均时间复杂度计算公式 A ( n ) = ∑ I ∈ S P I t I A(n) = \sum\limits_{I\in S}P_I t_I A(n)=I∈S∑​PI​tI​ 其中: S S ...

最新文章

  1. Ubuntu 16.04 安装 Docker - Dependency failed for Docker Application Container
  2. python 打印调用栈
  3. SQL中distinct的用法
  4. 11、E-commerce in Your Inbox:Product Recommendations at Scale-----产品推荐(prod2vec和user2vec)...
  5. android 反调试 方案,Android Native反调试—检测TracerPid值
  6. es6 find 数组内查询用法
  7. Docker热点文章链接 - 持续更新
  8. windows下mongodb安装与使用整理
  9. Windows 2008上安装VS2008SP1时的怪异错误
  10. python判断正确错误_python错误和异常
  11. struts2 iterator、append、merge标签总结
  12. python房屋租赁系统的设计与实现_基于ssh的房屋租赁系统的设计与实现(含源文件)...
  13. 在电脑前,写点什么...
  14. web前端顶岗实习总结报告_假期web前端实习报告
  15. alpha因子常见问题_因子体系(一):从因子确定到ALPHA和风险的界定
  16. 个人支付免费开通支付宝付款功能(免费签约)支付宝当面付开通集成到网站教程
  17. 快速确定dll 是x86还是x64
  18. 凸优化理论基础3——凸集和凸锥重要例子
  19. 【论文学习】基于区块链的档案数据保护和共享方法
  20. HEVC帧内预测参考相邻帧代码解析

热门文章

  1. 淘宝内核月报 2017
  2. Linux开启和关闭防火墙的方法
  3. smartSVN 分支与合并
  4. MySQL数据库中如何使用rand随机查询记录
  5. javascript 回车实现 tab 切换功能完美解决
  6. Linux救援模式实战
  7. vlc-android编译流程
  8. Expression Blend 利用 SketchFlow 制作原型
  9. mysql 插入学生信息_添加学生信息(连接数据库初学)
  10. java se 8 新特性_javase8-sample