HDU1556 Color the ball (樹狀數組)

一條簡單的樹狀數組題目,先寫好lowbit , update, sum三個函數。


考慮到sum函數只能求 從1 到某點的總和,所以需要更新兩次,更新是隻能更新從某點到最後的 , 這樣的話,先update(a,1) ,然後再 update(b ,-1)。


就能夠完成一次的更新過程了。


最後只要將結果求一下奇偶性即可 ,這個東西吧 …… 我本來是隻會 x%2 == 0這種方法的……後來有幸,受祖上福廕庇佑,能夠膜拜甫神的代碼, 崇敬之情之下發現了求奇偶性的如下代碼: x&1 , 好吧……年少無知啊。。。跑去百度了……


C++ 中, &運算符是位運算符,代表與運算, 與運算這種玩意 , 就是兩個二進制數, 補成相同位……一一對應一下……同一位置上的數,相同的就取相同的, 不同的就取0.

舉例: (10010010)&(00010100) = (0001000)


而x&1 這個吧,因爲 1的二進制數是(00000001),前面的0 可以加 ,這樣進行 與運算,得到的數只能是x 的最後一位,1就1 ,0就0,不發生變化。 而最後一位是 2的0次方,也就是1, 如果該位上是 0, 那麼就是偶數,如果是1,那麼x 就是奇數……


多麼奇妙的方法……膜拜甫神大人。


最後AC Memory : 688KB    Time : 796MS


代碼:

#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
int n;       
int ba[100001];  
int lowbit(int x)
{
   return (x)&(-x);
}
void update(int i,int x)
{
    while(i<=n)
    {
        ba[i]+=x;
        i+=lowbit(i);
    }
}
int sum(int x)
{
      int s=0;
      while(x>0)
      {
         s+=ba[x];
         x-=lowbit(x);
      }
      return s;
}
int main()
{
    int i, j, k;
    int a, b;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0) break;
        memset(ba, 0, sizeof(ba));

        for(i = 1; i <= n; ++i) {
            scanf("%d %d", &a, &b);
            update(a, 1);
            update(b+1, -1);
        }
        for(i = 1; i <= n; ++i) {
            printf("%d%c", sum(i), i == n?'\n':' ');
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章