zoukankan      html  css  js  c++  java
  • 树状数组使用总结

    树状数组使用总结

    在考试中 因为不清楚二维树状数组怎么用 而失手了无数遍了...
    今天终于把这个坑填了.... =_=

    1.区间修改+单点查询(一维)

    把查询第(x)个位置的值(s_x)变为查询前缀和(s_x = sum_{i = 1}^x d(i))
    其中 (d(x) = s_x - s_{x-1})
    修改([L,R])的时侯,只需要修改 (L)(R)+(1) 两个点。

    2.区间修改+区间查询(一维)

    查询([1,x]),则有:

    [res = sum_{i=1}^x s_x = sum_{i = 1}^x sum_{j = 1}^i d(j) ]

    [sum_{i = 1}^x sum_{j = 1}^i d(j) = sum_{j = 1}^x d(j)(x - j + 1) = (x+1)sum_{j = 1}^x d(j) - sum_{j = 1}^x d(j)j ]

    所以用两个树状数组分别维护(sum d(i))(sum d(i)*i)即可。

    3.单点修改+区间查询(二维)

    直接维护((1,1))((x,y))的这个矩阵的和即可。 代码类似一维处理即可:

    for( x ; x <= n ; x += lowbit(x) )
        for( y ; y <= m ; y += lowbit(y) )updata or query
    

    查询时用一下二维前缀和容斥一下就行了。

    4.区间修改+单点查询(二维)

    一样的转为差分值:(s_{{x,y}} = sum_{i = 1}^x sum_{j=1}^y d(i,j))
    其中$d(i,j) = s_{{x,y}} - s_{{x-1,y}} - s_{{x,y-1}} + s_{{x-1,y-1}} ( 修改时只修改)(x_1,y_1)(、)(x_1,y_2+1)(、)(x_2+1,y_1)(、)(x_2+1,y_2+1)$
    查询时一样的用 单点修改+区间查询(二维) 的方法查询。

    5.区间修改+区间查询(二维)

    [res = sum_{i=1}^x sum_{j=1}^y sum_{k=1}^i sum_{h=1}^j d(k,h) ]

    把后面两个(sum)提到前面来:

    [res = sum_{i=1}^x sum_{j=1}^y d(i,j)(x-i+1)(y-j+1) ]

    展开后得到:
    $res = res $

    $+(x+1)(y+1) [ sum_{i=1}^x sum_{j=1}^y d(i,j) ] ( )- (x+1) [ sum_{i=1}^x sum_{j=1}^y d(i,j)j ]( )- (y+1)* [ sum_{i=1}^x sum_{j=1}^y d(i,j)i ]( )+ [ sum_{i=1}^x sum_{j=1}^y d(i,j)ij ]( 所以用四个树状数组分别维护)sum d()$ , (sum d()i) , (sum d()j) , (sum d()ij) 即可 , 具体实现戳这里

  • 相关阅读:
    如何绕过chrome的弹窗拦截机制
    自我介绍
    注册页面的编写
    Roadmap学习目标
    Position
    poj2506 Tiling
    poj3278 Catch That Cow
    poj3624 Charm Bracelet
    钢条切割问题带你彻底理解动态规划
    poj1328 Radar Installation
  • 原文地址:https://www.cnblogs.com/GuessYCB/p/8459584.html
Copyright © 2011-2022 走看看