基本算法——前綴和與差分


一、前綴和

一維前綴和

  顧名思義,不再贅述。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N =1e6+10;
int n,m;
int a[N],sum[N];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    while(m--)
    {
        int l,r;scanf("%d%d",&l,&r);
        printf("%d\n",sum[r]-sum[l-1]);
    }
    return 0;
}

二維前綴和

  類似於容斥原理,手動畫圖很好理解。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1010;
int a[N][N],sum[N][N];
int n,m,q;
int main()
{
    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]);
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
        }
    while(q--)
    {
        int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%d\n",sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]);
    }
    return 0;
}

二、差分

  差分可以說是前綴和的逆運算。

  設原序列為a1,a2,…an,則該序列的差分序列b1,b2,…,bn滿足如下條件:ai = b1 + b2 + … + bi

一維差分

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

二維差分

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N =1010;
int a[N][N],b[N][N];
int n,m,q;
int main()
{
    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]);
            b[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];
        }
    while(q--)
    {
        int x1,y1,x2,y2,c;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
        b[x1][y1]+=c;
        b[x2+1][y1]-=c;
        b[x1][y2+1]-=c;
        b[x2+1][y2+1]+=c;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j];
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

附鏈接

一維前綴和

二維前綴和

一維差分

二維差分


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM