[算法笔记]分块算法从入门到TLE
分块算法在学习之前一直觉得是一个高端大气上档次,有着与众不同的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相关推荐
- 优化算法笔记|灰狼算法理解及Python实现
灰狼优化算法的理解和应用 一.背景介绍 二.算法原理 三.构建算法数学模型 四.Python实现GWO 五.算法分析 一.背景介绍 灰狼优化算法(Grey Wolf Optimizer,GWO)由澳大 ...
- 算法笔记_070-BellmanFord算法简单介绍(Java)
目录 1 问题描述 2 解决方案 2.1 具体编码 1 问题描述 何为BellmanFord算法? BellmanFord算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶 ...
- 回溯 皇后 算法笔记_算法笔记_04_回溯
设计思想: (1)适用:求解搜索问题和优化问题. (2)搜索空间:数,节点对应部分解向量,可行解在树叶上. (3)搜索过程:采用系统的方法隐含遍历搜索树. (4)搜索策略:深度优先,宽度优先,函数优先 ...
- 算法笔记_163:算法提高 最大乘积(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? 输入格式 第一行一个数表示数据组数 每组输入数据共2行: 第1行给出总共的数 ...
- 优化算法笔记|萤火虫算法理解及实现
萤火虫算法 一.萤火虫算法背景知识 二.萤火虫算法 三.萤火虫算法实现 四.算法分析 一.萤火虫算法背景知识 萤火虫算法(Firefly Algorithm, FA)是基于萤火虫的闪光行为,它是一种用 ...
- 算法笔记--KMP算法 EXKMP算法
1.KMP算法 这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html 模板: next数组的求解,那个循环本质就是如果相同前后缀不能加上该位 ...
- 算法笔记_167:算法提高 矩阵翻转(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 Ciel有一个N*N的矩阵,每个格子里都有一个整数. N是一个奇数,设X = (N+1)/2.Ciel每次都可以做这样的一次操作:他从矩阵 ...
- 算法笔记-排序算法(冒泡 选择 插入)
首先罗列一下常见的十大排序算法: 一.冒泡排序 1. 定义: 冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则 ...
- 【算法笔记】算法的平均时间复杂度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∑PItI 其中: S S ...
最新文章
- Ubuntu 16.04 安装 Docker - Dependency failed for Docker Application Container
- python 打印调用栈
- SQL中distinct的用法
- 11、E-commerce in Your Inbox:Product Recommendations at Scale-----产品推荐(prod2vec和user2vec)...
- android 反调试 方案,Android Native反调试—检测TracerPid值
- es6 find 数组内查询用法
- Docker热点文章链接 - 持续更新
- windows下mongodb安装与使用整理
- Windows 2008上安装VS2008SP1时的怪异错误
- python判断正确错误_python错误和异常
- struts2 iterator、append、merge标签总结
- python房屋租赁系统的设计与实现_基于ssh的房屋租赁系统的设计与实现(含源文件)...
- 在电脑前,写点什么...
- web前端顶岗实习总结报告_假期web前端实习报告
- alpha因子常见问题_因子体系(一):从因子确定到ALPHA和风险的界定
- 个人支付免费开通支付宝付款功能(免费签约)支付宝当面付开通集成到网站教程
- 快速确定dll 是x86还是x64
- 凸优化理论基础3——凸集和凸锥重要例子
- 【论文学习】基于区块链的档案数据保护和共享方法
- HEVC帧内预测参考相邻帧代码解析