二维矩阵前缀和+矩阵差分 板子

二维前缀和

//
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define maxnn 2000
long long  mapp[maxnn][maxnn];
int yyy=0;
int n,m;
int q;
int main()
{
    cin>>n>>m;
    int x1,y1,x2,y2;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&yyy);
            mapp[i][j]=mapp[i][j-1]+mapp[i-1][j]-mapp[i-1][j-1]+yyy;
        }
    }
    scanf("%d",&q);
    while(q--)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%lld\n",mapp[x2][y2]-mapp[x1-1][y2]-mapp[x2][y1-1]+mapp[x1-1][y1-1]);
    }
}

 

 

二维差分

//
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int n,m;
#define maxnn 2000
long long sum[maxnn][maxnn];
long long  a[maxnn][maxnn];
long long  mapp[maxnn][maxnn];
long long  d[maxnn][maxnn];
int main()
{
    int x,y;
    int p,q;
    cin>>n>>m;
    int x1,y1,x2,y2,k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&a[i][j]);
        }
    }
    cin>>p>>q;
    while(p--)
    {
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k);
        d[x1][y1]+=k;        //d[i][j]表示以(i,j)为左上角的差分值 前缀和就是该点的增量
        d[x1][y2+1]-=k;
        d[x2+1][y1]-=k;
        d[x2+1][y2+1]+=k;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+d[i][j];//前缀和
            a[i][j]+=sum[i][j];  加上增量
            mapp[i][j]=mapp[i-1][j]+mapp[i][j-1]-mapp[i-1][j-1]+a[i][j];前缀和
        }
        
    }
    while(q--)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%lld\n",mapp[x2][y2]-mapp[x1-1][y2]-mapp[x2][y1-1]+mapp[x1-1][y1-1]);
    }
    

}

 

posted @ 2019-08-19 22:55  ALEZ  阅读(220)  评论(0编辑  收藏  举报