首页 > 代码库 > 分块算法及模板

分块算法及模板

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

 

简要介绍

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

通常在分块时,每块的大小为√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%s30         //求最后一个块的大小 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  (数据较弱)

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

 

分块算法及模板