1. 程式人生 > >HDU-1556 Color the ball 【差分數組】

HDU-1556 Color the ball 【差分數組】

前綴 思想 bsp 前綴和 一個 sizeof all 屬於 pri

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[i],我們令d[i]=a[i]-a[i-1](d[1]=a[1]),則d[i]為一個差分數組,我們發現統計d數組的前綴和sum數組,則有 sum[i]=d[1]+d[2]+d[3]+...+d[i]=a[1]+a[2]-a[1]+a[3]-a[2]+...+a[i]-a[i-1]=a[i],即前綴和sum[i]=a[i];
因此每次在區間[l,r]增減x只需要令d[l]+x,d[r+1]-x,就可以保證[l,r]增加了x,而對[1,l-1]和[r+1,n]無影響。復雜度則是O(n)的。 (代碼為了體現思想,這題a和sum數組都可以省略)
代碼:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 0x3f3f3f3f
 4 #define M(a, b) memset(a, b, sizeof(a))
 5 const int N = 100000 + 10;
 6 int a[N], d[N], sum[N];
 7 
 8
int main() { 9 int n; 10 while (scanf("%d", &n), n) { 11 M(a, 0); 12 d[1] = a[1]; 13 for (int i = 2; i <= n; ++i) d[i] = a[i] - a[i-1]; 14 int l, r; 15 for (int i = 1; i <= n; ++i) { 16 scanf("%d%d", &l, &r); 17 d[l] += 1; 18 d[r+1] -= 1; 19 } 20 M(sum, 0); 21 for (int i = 1; i <= n; ++i) sum[i] = sum[i-1] + d[i]; 22 for (int i = 1; i < n; ++i) printf("%d ", sum[i]); 23 printf("%d\n", sum[n]); 24 } 25 26 return 0; 27 }

HDU-1556 Color the ball 【差分數組】