• 前缀和 && 差分


    前缀和

    • 对输入数组做预处理,可以快速求出数组中某连续一段元素的和

    前缀和

    //前缀和一定要让下标从1开始,便于定义s[0];
    //定义s[0]是为了方便处理边界情况,类似于“哨兵”技巧的作用,统一用一套代码覆盖所有情况,避免特判
    #include <iostream>
    
    using namespace std;
    
    const int N = 100010;
    
    int n, m;
    int a[N], s[N];
    
    int main() {
        //ios::sync_with_stdio(false);
        //加上面这句话后cin不需要与标准输入输出同步,从而提高输入的速度,加上这句话之后不能使用scanf
        scanf("%d%d", &n,&m);
        for(int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
        
        for(int i = 1; i <= n; i ++ ) s[i] = s[i-1] + a[i];
        
        while( m -- ) {
            int l, r;
            scanf("%d%d", &l, &r);
            printf("%d
    ", s[r] - s[l - 1]);
        }
        
        return 0;
    }
    

    前缀和技巧可以拓展到二维情况 子矩阵的和

    差分

    • 差分是前缀和的逆运算
    • 已知a数组,构造b数组,使得a是b的前缀和

    差分

    //差分的作用:对差分数组求前缀和,可以在O(n)时间内求得原数组
    //在O(1)时间内给原数组某一个固定区间内的数全部加上一个值
    #include <iostream>
    
    using namespace std;
    
    const int N = 100010;
    
    int n, m;
    int a[N], b[N];
    
    //给一个区间内的每个数增加c,这个函数也可以用来构造差分数组
    //在复原原数组(求前缀和)时,b[l]和b[r + 1]会作用于a[l]及之后的所有数,但是a[r + 1]之后的效果会被抵消
    void insert(int l, int r, int c) {
        b[l] += c;
        b[r + 1] -= c;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
        
        //开始时假设a中元素都为0,则对应的差分数组b中的元素都为零
        //下面这一步依次将a中的元素插入假想的初始元素全为零的数组中(比如将原数组的第i个元素由0变为a[i],相当于向差分数组的[i, i]区间插入a[i]),从而构造差分数组
        for(int i = 1; i <= n; i ++ ) insert(i, i ,a[i]);
        
        //在差分数组上面做操作
        while (m -- ) {
            int l, r, c;
            scanf("%d%d%d", &l, &r, &c);
            insert(l, r, c);
        }
        
        //求一下原来的数组(求前缀和)
        for(int i = 1; i <= n; i ++ ) b[i] += b[i - 1];
        
        for(int i = 1; i <= n; i ++ ) printf("%d ", b[i]);
        
        return 0;
    }
    

    拓展到二维情况 差分矩阵

  • 相关阅读:
    css字体属性相关。
    子级用css float浮动 而父级div没高度不能自适应高度
    转载:基于Redis实现分布式锁
    LeetCode(53):最大子序和
    LeetCode(52):N皇后 II
    LeetCode(51):N皇后
    LeetCode(50):Pow(x, n)
    LeetCode(49): 字母异位词分组
    LeetCode(48):旋转图像
    LeetCode(47):全排列 II
  • 原文地址:https://www.cnblogs.com/huhu555/p/14650566.html
Copyright © 2020-2023  润新知