树状数组小结

 

树状数组小结

第一次接触树状数组,a2pku上练习树状数组的基础题。故此做个总结。

树状数组理论来源:武钢三中 吴豪 树状数组

      一维树状数组相关函数:

//计算最小幂2^i

int Lowbit(int i)

{

         return i & (i ^ (i - 1));

}

 

//计算树状数组的前n项和

int Sum(int end)

{

         int sum = 0;

         while (end > 0)

         {

                   sum += Tree[end];

                   end -= Lowbit(end);

         }

         return sum;

}

//更新树状数组

void Update_Tree(int x)

{

         while (x < M)

         {

                   Tree[x]++;

                   x += Lowbit(x);

         }

}

相关练习:

http://acm.pku.edu.cn/JudgeOnline/problem?id=2352

AC代码:

#include <stdio.h>

#define M 32005

 

int n, Tree[M], ans[M];

 

//计算最小幂2^i

int Lowbit(int i)

{

         return i & (i ^ (i - 1));

}

 

//计算树状数组的前n项和

int Sum(int end)

{

         int sum = 0;

         while (end > 0)

         {

                   sum += Tree[end];

                   end -= Lowbit(end);

         }

         return sum;

}

 

void Update_Tree(int x)

{

         while (x < M)

         {

                   Tree[x]++;

                   x += Lowbit(x);

         }

}

 

int main()

{

         //freopen("1.txt", "r", stdin);

 

         int i, x, y;

         scanf("%d", &n);

         for (i = 0; i < n; i++)

         {

                   scanf("%d%d", &x, &y);

                   ans[Sum(x + 1)]++;     //别忘了数组下标从零开始

                   Update_Tree(x + 1);

         }

         for (i = 0; i < n; i++)

         {

                   printf("%d/n", ans[i]);

         }

         return 0;

}

                  

 

同样可以应用在二维的数组上:

int Lowbit(int x)

{

         return x & -x;

}

//

void update(int i, int j, int num)

{

    while (i > 0)

    {

        int temp = j;

        while (temp > 0)

        {

            Tree[i][temp] += num;

            temp -= Lowbit(temp);

        }

        i -= Lowbit(i);

    }

}

        

int sum(int x, int y)

{

         int temp = 0;

 

         for (int i = x; i <= N; i += Lowbit(i))

    {

                   for (int j = y; j <= N; j += Lowbit(j))

        {

                            temp += Tree[i][j];

                   }

         }

    return temp;

}

 

相关练习:

http://acm.pku.edu.cn/JudgeOnline/problem?id=2155

#include <stdio.h>

#include <string.h>

#define M 1005

 

int N, T;

int Tree[M][M];

 

int Lowbit(int x)

{

       return x & -x;

}

 

void update(int i, int j, int num)

{

    while (i > 0)

    {

        int temp = j;

        while (temp > 0)

        {

            Tree[i][temp] += num;

            temp -= Lowbit(temp);

        }

        i -= Lowbit(i);

    }

}

      

int sum(int x, int y)

{

       int temp = 0;

 

       for (int i = x; i <= N; i += Lowbit(i))

    {

              for (int j = y; j <= N; j += Lowbit(j))

        {

                     temp += Tree[i][j];

              }

       }

    return temp;

}

 

int main()

{

       //freopen("1.txt", "r", stdin);

       int i, test;

       int left1, right1, left2, right2;

       int x, y;

       char c[2];

 

       scanf("%d", &test);

       while (test--)

       {

              scanf("%d%d", &N, &T);

              memset(Tree, 0, sizeof(Tree));

              for (i = 0; i < T; i++)

              {

                     scanf("%s", c);

                     if (c[0] == 'C')

                     {

                            scanf("%d%d%d%d", &left1, &right1, &left2, &right2);

                            update(left2, right2, 1);  

                            update(left1 - 1, right2, -1);

                            update(left2, right1 - 1, -1);

                            update(left1 - 1, right1 - 1, 1);

                     }

                     else if (c[0] == 'Q')

                     {

                            scanf("%d%d", &x, &y);

                            printf("%d/n", sum(x, y) % 2);

                     }

              }

              printf("/n");

       }

 

       return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值