ACM训练日记—8月16日

来源:互联网 发布:java初级教程 编辑:程序博客网 时间:2024/05/29 13:24

         今天并没有怎么做题,开始正式的看有关树状数组的资料,大致有一点收获吧。

          树状数组,顾名思义就是建立数形状的数组,主要是用于方便快速的求和,设a[n],存储了n个数,那么C1 = A1;C2 = A1 + A2;C3 = A3;C4 = A1 + A2 + A3 + A4;C5 = A5;C6 = A5 + A6;C7 = A7;C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8;Cn = A(n – 2^k + 1) + ... + An(k是n的二进制末尾连续0的最长个数);由此递推下去建立一个c[n]数组就是树状数组,从递推式中不难看出树状数组具有明显的二分结构。因为树状数组的特殊结构,导致从上式中不难看出,如果对A[2],进行修改是不会影响到C3,但会影响C4,因为这种特殊结构,在重新求和时可以节省大量时间。下面看基础代码吧

     int lowbit(int x)//主要就是将x的二进制数的高位1全变0了,该函数实现求出2^m(m是k的二进制末尾连续0的个数)
     {
          return x&(-x);
     }
     int add(int i,int val)//将第i位数加val,同时对c[n]树状数组的更新
     {
         while(i<=n)
     {
        c[i]=c[i]+val;
        i=i+lowbit(i);//用这个运算可以求出下一个受到i位影响到的树状数组的位置
     }
     int sum(int i)//求出前i位的和
     {
          int ans=0;
          while(i>0)
          {
              ans=ans+c[i];
               i=i-lowbit(i);//找出影响这一位的上一个位置,进行累加
          }
          return ans;

     }

     今天的学习,对树状数组的理解暂时就这些,我还试着看了几篇博客,看的很吃力,明天还需看看模板在看博客。