【ACWING】前缀和、差分
前缀和
直接看模板题就好啦
前缀和
设有一个数列{a1,a2,a3...an},前缀和Sn=a1+a2+a3+...+an,就是数列的前n项和,其中,要求其下标从1开始,规定S0=0
- 如何求前缀和 :递归==>
S[n]=S[n-1]+a[i]
- 前缀和有什么用:求一段数组的和,比如求
[l,r]
数列之和,即S[r]-S[l-1]
//数列初始化 for(int i=1;i<=n;i++) scanf("%d",&a[i]); //前N项和初始化 for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]; //区间和公式 int l,r; cout<<s[r]-s[l-1]<<endl;
二维前缀和
求子矩阵的和
求(X1,Y1)到(X2,Y2)的大小
//二位矩阵的初始化,以及二维前缀和 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; //计算子矩阵 int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%d/n",s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]);
注意事项
1. 注意,这两种前缀和,我们习惯性下标从1开始
2. 关于全局数据的初始化和局部数组的初始化问题:对于全局数组,编译器默认初始化内容为0;对于局部数组(比如在main函数里的数组),默认初始化为随机数。所以如果我们采用全局数组,那么可以不写a[0]=0 S[0]=0 s[0][0]=0
差分(前缀和的逆运算)
已知有数列a[1],a[2],a[3]...a[n]
构造数列b[1],b[2],b[3]...b[n]
使得a[i]=b[1]+b[2]+...+b[i]
,此时,b称为a的差分。
显然,a是b的前缀和,如果我们知道b数组,那么就在O(n)时间能求得a数组
差分的用途:看模板题797
当然,这里我们不需要细想如何去构造b数组,可以假想a数组全为0,然后不断+a1,+a2,+a3....得到的
分类:
算法 / ACWING算法基础课
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步