zoukankan      html  css  js  c++  java
  • 基本算法——前缀和与差分

    一、前缀和

    一维前缀和

      顾名思义,不再赘述。

    #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
    ",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
    ",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("
    ");
        }
        return 0;
    }

    附链接

    一维前缀和

    二维前缀和

    一维差分

    二维差分

  • 相关阅读:
    java 可变參数列表
    Java -Xms -Xmx -Xss -XX:MaxNewSize -XX:MaxPermSize含义记录
    hdu 4939
    什么是堆和栈,它们在哪儿?
    PPAPI插件与浏览器的通信
    Java&amp;Xml教程(十一)JAXB实现XML与Java对象转换
    Heavy Transportation
    Python学习笔记-小记
    C/C++知识要点5——智能指针原理及自己定义实现
    小米2S电池电量用尽充电无法开机解决方法
  • 原文地址:https://www.cnblogs.com/ninedream/p/11537576.html
Copyright © 2011-2022 走看看