前缀和模板

本文详细介绍了前缀和算法在处理区间求和问题时的应用,包括一维和二维情况下的实现方法,通过实例展示了如何利用前缀和降低时间复杂度,达到高效求解的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前缀和:用来快速求区间的和

输入一个长度为n的整数序列。

接下来再输入m个询问,每个询问输入一对l, r。

对于每个询问,输出原序列中从第l个数到第r个数的和。

1≤l≤r≤n,
1≤n,m≤100000,
−1000≤数列中元素的值≤1000

我们如果每次都把l到r区间的数加起来,那么在数据最大的情况下,时间复杂度就达到了O(1e10+),这样我们显然是不能接受的
这时候就用到的前缀和思想


我们定义一个数组a用来存放输入的元素,然后再定义一个数组存放前i个元素的和(包括第i个元素),那么,如果我们求l到r区间的和,我们直接求s[r]-s[l-1]就可以,这样表示前r个元素的和减去前l-1个元素的和,这样就得到闭区间l到r的和,这样的时间复杂度是O(m+n)


#include<iostream>
using namespace std;
const int N=1e5+5;
int a[N],n,q;
int main()
{
    int l,r;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) scanf("%d",a+i),a[i]+=a[i-1];
    while(q--)
    {
        scanf("%d%d",&l,&r);
        printf("%d\n",a[r]-a[l-1]);
    }
    return 0;
}

一维的比较简单,二维的也话也是同样的思想,只不过是需要考虑的周到一些
子矩阵和
在这里插入图片描述


假定我们要求(i-1,j-1)到(i,j)围城矩阵的和,那么我们求出(0,0)到(i,j)的面积,然后减去除蓝色区域的面积即可,重点来了!!!
我们不可能分别求红色、浅蓝色、绿色三块的和,因为浅蓝色和绿色的和不好求,但是利用前缀和红色的和基本就是已知的,那么我们直接求红色+浅蓝色的和、红色+绿色的和即可,然后再减去多计算一次的红色的面积即可(容斥原理),这样的话时间复杂度为O(n*m+q)


#include<iostream>
using namespace std;
const int N=1e3+5;
int a[N][N],n,m,q,s[N][N];
int main()
{
    int x1,y1,x2,y2;
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&a[i][j]),s[i][j]=s[i-1][j]+s[i][j-1]+a[i][j]-s[i-1][j-1];
    while(q--)
    {
        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]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值