分块算法及模板

此文为博主原创,转载时请通知博主,并把原文链接放在正文醒目位置。

简要介绍

分块算法就是把一串数据分割成几块数据的算法,其实是对暴力的一种优化。

通常在分块时,每块的大小为√n。但最后一块的大小也可能小于√n,只能用暴力来算。

通过把对单个数据的操作转化为对几个块的数据的操作,能够节省时间,提高运算效率。

分块算法在处理大范围的修改、查询问题时有很大优势。

分块算法代码

 1 /*此代码主要模仿了钟皓曦大佬的分块算法*/
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6
 7 using namespace std;
 8 const int MAXN = 1000005;
 9 const int MAXP = 1005;
10 int belong[MAXN],size[MAXP],sum[MAXP],add[MAXP];
11 //    所属块        块的大小    块内计和  添加标记
12 int a[MAXN];
13 int s,cnt;
14
15 void init()
16 {//初始化操作
17     s = sqrt(n);//每个块的大小
18     for(int i = 1;i <= n;i ++)
19         belong[i] = (i-1)/s + 1;
20     //每个数的所属块
21     cnt = belong[n];//块的数量
22
23     for(int i = 1;i <= cnt;i ++)
24     {//记录块的大小
25         sum[i] = add[i] = 0;
26         if(i == cnt)
27         {
28             if(n%s == 0)    size[i] = s;
29             else    size[i] = n%s
30         //求最后一个块的大小
31         }
32         else size[i] = s;
33     }
34 }
35
36 int query(int l,int r)
37 {//询问操作
38     int ans = 0;
39     if(belong[l] == belong[r])
40         ans += sum[belong[l]];
41     //询问区间在一个块里的情况
42
43     while(belong[l] == belong[l - 1])
44     {//询问区间在整块左侧的情况
45         ans += a[l] + add[belong[l]];
46         l ++;
47     }
48     while(belong[r] == belong[r + 1])
49     {//询问区间在整块右侧的情况
50         ans += a[r] + add[belong[r]];
51         r --;
52     }
53     for(int i = belong[l];i <= belong[r];i ++)
54     //对整块进行求和操作
55         ans += sum[i];
56     return ans;
57 }
58
59 void modify(int l,int r,int k)
60 {//修改(增减值)操作
61     if(belong[l] == belong[r])
62     {//修改区间在一个块内的情况
63         for(int i = l;i <= r;i ++)
64             a[i] += v;
65         return;
66     }
67     while(belong[l] == belong[l - 1])
68     {//修改区间在整块左侧的情况
69         a[l] += v;
70         l ++;
71     }
72     while(belong[r] == belong[r + 1])
73     {//修改区间在整块右侧的情况
74         a[r] += v;
75         r --;
76     }
77     for(int i = belong[l];i <= belong[r];i ++)
78     {//对整块进行增减操作
79         add[i] += v;//标记一个块
80         sum[i] += size[i]*v;
81     }
82 }

分块算法例题

洛谷 P1903 【模板】分块/带修改莫队(数颜色)   https://www.luogu.org/problem/show?pid=1903

洛谷 P2801 教主的魔法   https://www.luogu.org/problem/show?pid=2801  (数据较弱)

(不知道为什么,洛谷的算法标签里没有“分块”)

时间: 2024-11-18 19:44:22

分块算法及模板的相关文章

hdu 5057 Argestes and Sequence(分块算法)

Argestes and Sequence Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 566    Accepted Submission(s): 142 Problem Description Argestes has a lot of hobbies and likes solving query problems espec

【快速处理】分块算法

分块算法 ---------------------------------------------------------- 1.思想 如果我们需要对一个特定的序列进行操作,那么非常直观.简单的方法就是纯暴力(不,那叫模拟). 不过如果暴力能过的话,那就呵呵了. 所以我们要想一些比较高能的数据结构——分块. 相比线段树来说,分块算法比较难实现,但是只要深入理解,就可以实现了,只不过需要一些数据结构的辅助. 分块实质来说就是把一个序列切分,从而实现对查询.查找.替换等等操作的高效处理. ----

图论算法-Tarjan模板 【缩点;割顶;双连通分量】

图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; bool ins[100010]; int col[100010];//记录每个点所属强连通分量(即染色) vector<int> map[100010]; stack<int> st; int tot;//时间戳 int colnum;//记录强连通分量个数 void tarjan(

【基本算置顶】各大算法&amp;&amp;数据结构模板

板子,全是板子 更新日志(从2018.11.19开始) 2018.12.02 : 更新了数据结构->扫描线 2018.11.22 : 更新了数据结构->平衡树->FHQ Treap->维护区间操作 2018.11.20 : 更新了数论->博弈论->nim游戏 2018.11.20 : 更新了数据结构->平衡树->FHQ Treap 观摩本蒟蒻板子库的大佬数: 不断更新 一.数论 1.快速幂 2.欧拉函数 3.乘法逆元(线性求逆) 4.线性筛素数 5.扩展欧几

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

URAL 1099 Work scheduling 一般图的最大匹配 带花树算法(模板)

R - Work scheduling Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 1099 Description There is certain amount of night guards that are available to protect the local junkyard from possible junk r

刷题总结——分块算法(bzoj2821作诗)

题目: Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗 之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一 些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认 为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选 法.LYD这

AC自动机算法及模板

关于AC自动机 AC自动机:Aho-Corasickautomation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过.要搞懂AC自动机,先得有模式树(字典树)Trie和KMP模式匹配算法的基础知识.AC自动机算法分为3步:构造一棵Trie树,构造失败指针和模式匹配过程. 简单来说,AC自动机是用来进行多模式匹配(单个主串,多个模式串)的高效算法. AC自动机的构造过程 使用Aho-

分块算法

有一种很常见的题型  就是一个在一个好长的序列中进行 乍一看都是很麻烦的那种 修改和查询. 通常这种题 都是拿高端的数据结构 轻轻松松优化查询修改复杂度写过去,可是不会怎么办??! 于是就可以利用分块这种小技巧了. 这个技能就算是带奇技淫巧的暴力吧,暴力出奇迹. 简单来说 : 这种思路就是 把序列分成很多个块, 建立块与块之间的联系,然后每次修改就只需要改一个块里的东西. 如果分成 √N 块,每块有 √N 个 , 那么每次修改 查询 的操作 就都被减到了以前的根号级别, 所以就可以水过好多题 看