首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >简单前缀和

简单前缀和

作者头像
AngelNH
发布于 2020-04-16 11:53:14
发布于 2020-04-16 11:53:14
7280
举报
文章被收录于专栏:AngelNIAngelNI

一切都在潜移默化中ing

【问题引入】

给定n个数,再给出m个询问,每个询问给出区间(i,j)和x,要求 i 到 j 的每一个值都加上x,最后给出每一个询问区间(i,j)的区间和。

暴力:O(n^2);线段树或者树状数组O(logn);差分O(n);

前缀和

下图为前缀和的定义式和递推式

差分

什么是差分?差分是一个数组相邻两元素的差,一般为下标靠后的减去靠前的一个。设差分数组p[],即:

p[i] = a[i] - a[i - 1]

前缀和 和 差分 的联系

令F(a)表示前缀和数组,G(a)表示差分数组,则 F(G(a)) = G(F(a)) = a

前缀和 和 差分 是一对互逆过程。

一维前缀和

根据上述表达式我们可以以O(1)求出区间[i,j]的区间和 sum(i,j) = a[j] - a[i-1]

通过一维前缀和可求得数组中前 i 个元素的和

二维前缀和

b[ i ] [ j ] = b[ i - 1 ] [ j] +b[ j ] [ j - 1] -b[ i-1] [ j - 1] + a[ i ] [ j ]

练习

51nod1081子段求和

代码语言:javascript
复制
#include<iostream>
#include<cstdlib>
using namespace std;
typedef long long ll;
ll m,n,a[100000],b[100000];
ll x,y;
int main()
{
    cin>>n;
    b[0] = 0;
    for(ll i =1;i<=n;++i)
    {
        cin>>a[i];
        b[i] = b[i-1]+a[i];
        
    }
    // for(int i =1;i<=n;++i)
    //     cout<<b[i]<<" ";
    cout<<endl;
    cin>>m;
    while(m--)
    {
        cin>>x>>y;
        printf("%lld\n",b[x+y-1]-b[x-1]);
    }
    system("pause");
    return 0;
}

HDU1559最大子矩阵

代码语言:javascript
复制
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int t;
int mp[1005][1004];
int b[1005][1005];
int n,m,x,y;
int main()
{
    cin>>t;
    while(t--)
    {
        memset(b,0,sizeof(b));
        cin>>m>>n>>x>>y;
        for(int i =1;i<=m;++i)
        {
            for(int j =1;j<=n;++j)
            {
                cin>>mp[i][j];
                b[i][j] = b[i-1][j]+b[i][j-1]-b[i-1][j-1]+mp[i][j];
            }
        }
        int ans=0;
        for(int i =x;i<=m;++i)
        {
            for(int j =y;j<=n;++j)
            {
                ans=max(ans,b[i][j]-b[i-x][j]-b[i][j-y]+b[i-x][j-y]);
            }
        }
       cout<<ans<<endl;

    }
    system("pause");
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-30|,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 前缀和
  • 差分
  • 一维前缀和
  • 二维前缀和
  • 练习
    • 51nod1081子段求和
    • HDU1559最大子矩阵
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档