zoukankan      html  css  js  c++  java
  • 树状数组——学习笔记

    树状数组——学习笔记

    大佬blog

    前置知识

    前缀和

    关于数组a

    s[i]=s[i-1]+a[i]

    差分(区间修改)

    e.g 对于集合A = { x , y , z , w , u , v },将y,z和w分别加上a,求操作后数组.

    集合C = { x , y-x , z-y , w-z , u-w , v-u }       //这叫差分

    集合C‘ = { x , y-x+a , z-y , w-z , u-w-a , v-u }

    集合ANS = { x , y+a , z+a , w+a , u , v }       //求前缀和

    原理

    红:C[i]             代表树状数组

    黑:A[i]             代表普通数组

    C[1] = A[1];

    C[2] = A[1] + A[2];

    C[3] = A[3];

    C[4] = A[1] + A[2] + A[3] + A[4];

    C[5] = A[5];

    C[6] = A[5] + A[6];

    C[7] = A[7];

    C[8] = A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7] + A[8];

    所以

    C[i] = A[i - 2k+1] + A[i - 2k+2] + ... + A[i]; //k为i的二进制中从最低位到高位连续零的长度

    怎么求呢?

    lowbit( x )

    引入一个新函数——lowbit( x )

    指一个二进制数从低位到高位第一个非零数连上后面的零所组成的另一个二进制数

    e.g 4(10)=100(2)

          lowbit(4)=4

          7(10)=111(2)

          lowbit(7)=1

          12(10)=1100(2)

           lowbit(12)=4

    位运算实现:lowbit( i ) = i & ( -i )

    回来

    树状数组中下标为i的点维护的是线段树下标为[i-lowbit(i)+1,i]这个区间数值的和

    好der

    操作

    前缀查询

    拆分

    #define lowbit(x) x&(-x)
    int query(int s[],int node){
    int sum = 0;
       while(node){
    sum += s[node];
           node -= lowbit(node);
      }
       return sum;
    }

    单点修改

    #define lowbit(x) x&(-x)
    void update(int s[],int x,int val){
       while(x<=n){
    s[x] += val;
           x += lowbit(x);
      }
       return;
    }

    P3374

    P3368(用到了差分 测试数据模拟一下就清楚了)

    LOJ#132(绝了,过不去)大佬blog(主要看推导)

    P1908

    P2345

    P3605

    P1972

    P4113

    P3431(不会算了)

    P3608

    P3660

    P4054

    P4514

  • 相关阅读:
    精准测试
    git 管理
    git
    代码覆盖率测试
    vue 前端视频
    jenkins
    go学习资料
    4-4 求自定类型元素的平均
    4-3 简单求和
    4-2 多项式求值
  • 原文地址:https://www.cnblogs.com/wsyunine/p/14223579.html
Copyright © 2011-2022 走看看