Color the ball HDU - 1556 線段樹區間更新點查詢

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


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=100020;
struct node
{
    int l,r,n;
}tree[M<<2];
int n;
int ans[M];
void build(int l,int r,int k)
{
    tree[k].l=l;tree[k].r=r;
    tree[k].n=0;
    if(l==r)
        return ;
    int mid=(l+r)>>1;
    build(l,mid,k<<1);
    build(mid+1,r,k<<1|1);
}
void update(int l,int r,int k)
{
    if(tree[k].l>=l&&tree[k].r<=r)
    {
        tree[k].n++;
        return ;
    }
    int mid=(tree[k].l+tree[k].r)>>1;
    if(l<=mid)
        update(l,r,k<<1);
    if(r>mid)
        update(l,r,k<<1|1);
}
void add(int k)
{
    if(tree[k].n)
        for(int i=tree[k].l;i<=tree[k].r;i++)
        ans[i]+=tree[k].n;
    if(tree[k].r==tree[k].l)
        return ;
    add(k<<1|1);
    add(k<<1);
}
int main()
{
    int a,b;
    while(scanf("%d",&n),n)
    {
        build(1,n,1);
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            update(a,b,1);
        }
        add(1);
        for(int i=1;i<=n;i++)
        {
            printf("%d%c",ans[i],i==n?'\n':' ');
        }
    }
    return 0;
}


發佈了120 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章