• 学习笔记——二维树状数组


    不知道为什么,就是想把这个坑给填了。。。

    二维树状数组,本质上还是树状数组,只是在一维的基础上变成了二维。。。

    单点修改  1到i,j查询和一维基本一样,直接上代码

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define N 3010
    using namespace std;
    int a[N][N],n;
    inline int lowbit(int x){
        return x&-x;
    }
    inline add(int x,int y,int del){
        for(int i=x;i<=n;i+=lowbit(i))
            for(int j=y;j<=n;j+=lowbit(j))
                a[i][j]+=del; 
    }
    inline sum(int x,int y){
        int num=0;
        for(int i=x;i;i-=lowbit(i))
            for(int j=y;j;j-=lowbit(j))
                num+=a[i][j];
        return num;
    }
    inline void Jimmy(){
    }
    int main(){
        Jimmy();
        return 0;
    } 
    二维树状数组 单点修改 1到i,j查询

    下面介绍一下区间修改和区间查询

    定义bi,j表示i,j到n,n的修改量,实质是一个标记,在计算sigma时我们通过统计区间内标记个数得出区间修改量之和

    我们设面积前缀和S

    那么S(x,y)=sigma(i<=x and j<=y) ai,j +sigma(i<=x and j<=y) bi,j*(x-i+1)*(y-j+1)

         =sigma(i<=x and j<=y) ai,j +sigma(i<=x and j<=y) bi,j*(x+1)*(y+1)-sigma(i<=x and j<=y) bi,j*i*(y+1)-sigma(i<=x and j<=y) bi,j*j*(x+1)+sigma(i<=x and j<=y) bi,j*i*j

    所以我们维护四个数组 bi,j  bi,j*i  bi,j*j  bi,j*i*j  就可以在logn时间内来完成查询了

    区间修改呢,就是在矩形的四个角分别打上标记

    x1,y1 +del
    x2+1,y1 -del
    x1,y2+1 -del
    x2+1,y2+1 +del

    每个标记修改4个数组,一共16次

    然后就ok啦

    (这里原来是一份错误的代码。。。果然还是理解错了,关于树状数组见新的一份整合版吧)  2017.4.09

    学习来源:http://tonyfang.is-programmer.com/posts/206991.html

    orzTonyFang

  • 相关阅读:
    总账数据访问安全性控制(5)
    XML输出中文时,无法用xsl查看(XML文件不能正常显示、中文显示乱码)
    设计抗混叠滤波器的三大指导原则(转载)
    Verilog中变量位宽注意
    学习cordic算法所得(流水线结构、Verilog标准)
    傅里叶分析的理解
    转载:Allegro实用技巧之模块复用
    c语言学习之 辗转相除法求最大公约数
    c语言学习之 正序分解整数
    新博客开张
  • 原文地址:https://www.cnblogs.com/JimmyC/p/6664202.html
Copyright © 2020-2023  润新知