zoukankan      html  css  js  c++  java
  • 前缀和与差分

    前缀和与差分

    先记一下前缀和,比较简单。

    前缀和

    一维前缀和

    一维前缀和:能以(O(1))的时间完成求一段区间上的和。

    定义:s[i] = a[1] + a[2] + ... + a[i]

    求解(l-r)上的和就是s[r]-s[l-1]

    二维前缀和

    就是把一维的拓展了一下,相对应的求解s[i]的方式会稍微更复杂一点

    定义:S[i][j] = 第i行j列格子左上部分所有元素的和

    接下来的画个图很好理解,求一块子矩阵(x1y1x2y2)的方式就是:

    Sum = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + S[x1 - 1][y1 - 1]

    差分

    差分是前缀和的逆运算,相对难理解一点。

    原数组a[n]就是差分数组s[n]的前缀和数组

    差分的作用:能以(O(1))的时间来完成区间上的加法。

    其实要求差分数组比较难,最简单的理解方式:

    先想象原数组a[n]全是0,每次向里加一个数字,就是对这一块的区间进行了一次加法。

    所以差分只有一个功能,就是向一段区间同时增改一个数字。建立差分数组也用这个思想。

    一维差分

    自己推一下就知道,在差分数组里,向s[i]加一个数val,会影响向后所有的数据,所以在s[r+1]里补回来即可。

    [l,r]进行一次加法: s[l] += val,s[r+1] -= val

    二维差分

    和一维差分同样的思想,只不过更难推一点。

    x1y1x2y2同时加一个数的方法是:

    void insert(int x1, int y1, int x2, int y2, int val)
    {
        s[x1][y1] += val;
        s[x2 + 1][y1] -= val;
        s[x1][y2 + 1] -= val;
        s[x2 + 1][y2 + 1] += val;
    }
    
  • 相关阅读:
    洛谷 P2384 最短路
    洛谷 P2910 [USACO08OPEN]寻宝之路Clear And Present Danger
    POJ 3264 Balanced Lineup
    洛谷 P1892 团伙
    洛谷 P1724 东风早谷苗
    P1129 [ZJOI2007]矩阵游戏
    P1894 [USACO4.2]完美的牛栏The Perfect Stall
    Poj 3041 Asteroids
    P3377 【模板】左偏树(可并堆)
    P1613 跑路
  • 原文地址:https://www.cnblogs.com/Salty-Fish/p/13526149.html
Copyright © 2011-2022 走看看