程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 1556 Color the ball - from lanshui_Yang

HDU 1556 Color the ball - from lanshui_Yang

編輯:C++入門知識

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  

        這是一道典型的一維樹狀數組的變形,普通的一維樹狀數組的用途是:單點更新,區間求值。而這道題的則是用到樹狀數組的另一個用途:區間更新,單點求值。原理如下:

      假設原始數組的各個元素為a[1] , a[2] ,…… a[n] ,  那麼 d[n] = a[1] + a[2] + …… + a[n] 求的就是前n項和,這就是樹狀數組的第一個用途:單點更新,區間求和。

       然後,稍微做些改動,假設原始數組的各個元素為a[1] - 0 , a[2] - a[1] , a[3] - a[2] ,……,a[n] - a[n - 1] , 那麼此時的前n項和 d[n] = a[n] ,也就是說,現在原始數組的前n項和d[n]  就等於單點的值a[n] 了 ,大家看到這裡是不是就有些明白了呢?

       接著,如果你想時區間[  a[m] …… a[n]  ] 中的所有值都 + Val ,那麼只需將原始數組的第m項 (a[m] - a[m - 1] )  加上 Val  , 和將第n + 1項 (a[n + 1] - a[n])  減去 Val 就可以了, 這樣當 m <= i <= n 時 ,

       數列的前 i 項和:

       d[i] = (a[1] - 0) + (a[2] - a[1]) + (a[3] - a[2]) + …… + (a[m] - a[m - 1] + val) + (a[m + 1] - a[m]) + …… + (a[i] - a[i - 1] )  = a[i]  + val 。 

       同理當 i > n 時 ,d[i] 等於原來的 a[i]  。看到這裡,大家是不是就豁然開朗啦。注意一點,這裡a[1] …… a[n] 的初始值均為0 !! 

       下面請看代碼:

 

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int C[MAXN] ;
int n ;
int lowbit (int x)
{
    return x & -x ;
}
void add(int x , int d)
{
    while(x <= n)
    {
        C[x] += d ;
        x += lowbit(x) ;
    }
}
int sum(int x)
{
    int sumt = 0 ;
    while (x > 0)
    {
        sumt += C[x] ;
        x -= lowbit(x) ;
    }
    return sumt ;
}
int main()
{
    while (scanf("%d" , &n) != EOF)
    {
        if(n == 0 )
            break ;
        memset(C , 0 , sizeof(C)) ;
        int t = n ;
        int i ;
        while ( t-- )
        {
            int a , b ;
            scanf("%d%d", &a , &b) ;
            add(a , + 1) ;
            add(b + 1 , -1) ;
        }
        for(i = 1 ; i <= n ; i ++)
        {
            printf("%d" , sum(i)) ;
            if(i < n)
                printf(" ") ;
        }
        puts("") ;
    }
    return 0 ;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved