HDU 1556 Color the ball(線段樹區間更新)

原題地址

Color the ball

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


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

我們可以只更新區間的值,而不更新單點的值。如果將1~10的氣球刷一遍,我們只需要將相應區間的值+1。最後計數的時候,在區間內的點的值都加上該區間的值。也就是區間的權值代表該區間的氣球被刷的次數。
下面貼代碼:
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int left;
    int right;
    int data;
}tree[300000];
void bTree(int root,int l,int r)//建樹
{
    tree[root].left=l;
    tree[root].right=r;
    tree[root].data=0;
    int mid=(l+r)/2;
    if(tree[root].left==tree[root].right)
    {
        return;
    }
    bTree(root*2,l,mid);
    bTree(root*2+1,mid+1,r);

}
void uTree(int root,int l,int r)//更新樹
{
    if(tree[root].left==l&&tree[root].right==r)//更新區間的值而不更新單點和子區間的值。最後再累加
    {
        tree[root].data+=1;
        return;
    }
    int mid=(tree[root].left+tree[root].right)/2;
    if(r<=mid)
    {
        uTree(root*2,l,r);
    }
    else if(l>mid)
    {
        uTree(root*2+1,l,r);
    }
    else
    {
        uTree(root*2,l,mid);
        uTree(root*2+1,mid+1,r);
    }
}
int sum[100011];
void sTree(int root)//遍歷樹,如果一個點在該區間內,加上該區間的權值。
{
    for(int i=tree[root].left;i<=tree[root].right;i++)
    {
        sum[i]+=tree[root].data;
    }
    if(tree[root].left==tree[root].right)
    {
        return;
    }
    sTree(root*2);
    sTree(root*2+1);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        //printf("%d\n",n);
        if(n==0) break;
        memset(sum,0,sizeof(sum));
        bTree(1,1,n);
        int t=n;
        while(t--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            uTree(1,a,b);
        }
        sTree(1);
        for(int i=1;i<n;i++)
        {
            printf("%d ",sum[i]);
        }
        printf("%d\n",sum[n]);
    }
    return 0;
}


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