一條簡單的樹狀數組題目,先寫好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;
}