1. 程式人生 > >Color the ball +數狀陣列(一維)

Color the ball +數狀陣列(一維)

Color the ball

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 28569    Accepted Submission(s): 13944

Problem Description

N個氣球排成一排,從左到右依次編號為1,2,3....N.每次給定2個整數a b(a <= b),lele便為騎上他的“小飛鴿"牌電動車從氣球a開始到氣球b依次給每個氣球塗一次顏色。但是N次以後lele已經忘記了第I個氣球已經塗過幾次顏色了,你能幫他算出每個氣球被塗過幾次顏色嗎?

Input

每個測試例項第一行為一個整數N,(N <= 100000).接下來的N行,每行包括2個整數a b(1 <= a <= b <= N)。 當N = 0,輸入結束。

Output

每個測試例項輸出一行,包括N個整數,第I個數代表第I個氣球總共被塗色的次數。

Sample Input

3 1 1 2 2 3 3 3 1 1 1 2 1 3 0

Sample Output

1  1 1 3 2 1

AC程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100000 + 10;
int tree[maxn];
int n;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int val){
    while(x<=n){
        tree[x]+=val;
        x+=lowbit(x);
    }
}
int query(int x){
    int ans = 0;
    while(x > 0){
        ans += tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    int x,y;
    while(cin >>n && n){
        memset(tree,0,sizeof(tree));
        for(int i=1;i<=n;++i){
            scanf("%d %d",&x,&y);
            update(x,1);
            update(y+1,-1);
        }
        for(int i=1;i<=n;++i){
            if(i!=1){
                printf(" ");
            }
            printf("%d",query(i));
        }
        puts("");
    }
     return 0;
}

附上線段樹的AC程式碼:

#include <iostream>
#include <cstring>
#include <cmath>
using  namespace std;
#define lson re<<1,l,mid
#define rson re<<1|1,mid+1,r
const int maxn = 100000+100;
int num[maxn<<2];
void build(int re,int l,int r){
    if(l==r){
       return;
    }
    int mid = (l+r)>>1;
    build(lson);
    build(rson);
}
void update(int re,int l,int r,int L,int R){
    if(l==L && r==R){
        num[re]++;
        return;
    }
    int mid = (l+r)>>1;
    if(R<=mid) update(re<<1,l,mid,L,R);
    else if(L>mid) update(re<<1|1,mid+1,r,L,R);
    else{
        update(re<<1,l,mid,L,mid);
        update(re<<1|1,mid+1,r,mid+1,R);
    }
    return;
}
int query(int re,int l,int r,int L,int R){
    if(l==L && R==r){
        return num[re];
    }
    int mid = (l+r)>>1;
    if(R<=mid)  return num[re]+query(re<<1,l,mid,L,R);
    else if(L>mid) return num[re]+query(re<<1|1,mid+1,r,L,R);
    else{
        return num[re]+query(re<<1,l,mid,L,R)+query(re<<1|1,mid+1,r,L,R);
    }
}
int main(){
    int n,x,y;
    while(cin >> n && n){
        memset(num,0,sizeof(num));
        build(1,1,n);
        int m = n;
        while(n--){
            cin >> x >> y;
            if(x<y)
            update(1,1,m,x,y);
            else
            update(1,1,m,y,x);
        }
        for(int i=1;i<=m;++i){
            if(i!=1){
                cout << ' ';
            }
            cout << query(1,1,m,i,i);
        }
        cout << endl;
    }
    return 0;
}