• 前缀和及其应用


    前缀和,简单来说,你输入了一串数,用s[i]表示a[1]~a[i]的所有元素的和,那么s数组记录的就是a的前缀和。

    用前缀和来进行维护可以很好地节约时间复杂度,比如说有一串数,每次给定一个操作,询问一段区间内所有元素和,要求线性做法O(m+n),这时就不能使用两重循环枚举。我们可以使用前缀和,当询问区间l~r时,我们只要输出s[l]-s[r]就可以了。

    前缀和同样可以用在矩阵上,如果用f[i][j]来表示从(1,1)到(i,j)之间所有元素的和,这样的话初始化代码就是:

    f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];

    这样我们在询问一个矩阵中的元素和时,他的计算公式就是

    f[i][j] - f[x - 1][j] - f[i][y - 1] + f[x - 1][y - 1];

    下面我们来看其他的应用。

    例题1:

    给定n个数ai,有m次操作,每个操作是给al~ar增加一个数k。最终输出操作完后的这n个数的值。要求一个O(n+m)的做法。

    这种题怎么做呢?如果按最暴力的想法,我们会在每个询问区间内,进行一次循环,但是这样的作法不是线性的,不符合要求。

    我们要选择具有代表性的元素来下手,也就是那些发生改变较少的元素。——张浩威

    哪些元素的改变比较少呢?我们在一次区间操作之后,区间内的元素都发生了改变,显然不好,我们仔细观察后发现,区间端点与其旁边元素的差值变化比较小。如果在一段区间内+=i,那么就让左端点和其前面的元素的差值+2,右端点和其后面元素的差值-2。这样我们就可以做到线性操作了,只要开一个数组f来记录当前元素和前一个元素的差值即可。

    此时我们会发现,a数组其实就是f数组的前缀和!也就是说这道题也可以转换成前缀和来做了。

    矩阵的话也大致相同。

    对于每次以(x,y)为左上角,(x2,y2)为右下角的矩阵操作,相当于是令s[x][y]+=k,s[x][y2+1]-=k,s[x2+1][y]-=k,s[x2+1][y2+1]+=k。

  • 相关阅读:
    MySQL Unknown table engine 'FEDERATED''
    Meta http-equiv属性与HTTP头的Expires中(Cache-control)详解
    EChart 标题 title 样式,x轴、y轴坐标显示,调整图表位置等
    手机端个人信息模板
    <c:forEach>, <c:forTokens> 标签
    html select 可输入 可编辑
    js写评价的星星
    指数映射
    刚体转动的稳定性
    物理引擎中的刚体转动2
  • 原文地址:https://www.cnblogs.com/captain1/p/8424201.html
Copyright © 2020-2023  润新知