Color the ball(樹狀數組)

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
 
 
Source
 
 
最近在學樹狀數組,老師給我們了這道題,想了好久也不覺得它和之前學的樹狀數組有什麼關係,那種與二進制相關的儲存方式,不好修改也不好訪問。而且是給定區間,訪問點,和之前那種給點,修改父親節點,訪問區間完全不一樣。呵呵O(∩_∩)O,整個人都要瘋掉
 

解答:

a數組是每個氣球的塗色次數,在這種解答裏沒有用,所以我沒有定義出來,寫在這裏只是爲理解方便

定義一個b數組 b[i]=a[i]-a[i-1]  ( b[0]=0 所以是不是 b[1]=a[1] )

易知 a[k]=a[k-1]+b[k] ,a[k-1]是不是也可以分解成這種形式,最後a[i]=b[1]+b[2]+b[3]+…+b[i] 

 

當給一個start,end,在【start,end】區間裏的所有點是不是都要加1

換句話說,是不是這段區間內的差值,,也就是b是沒變的( b[start+1] ~ b[end] ),唯一改變的只是b[start] 加了1和 b[end+1]減了1 而已

所以 每次操作只需修改兩個變量

 

程序:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
 int b[500000],n,s,e;
 
 while(1)
 {
  memset(b,0,sizeof(b));
  
  scanf("%d",&n);
  if(!n) return 0;
  
  //printf("#case \n");
  
  for(int i=1;i<=n;i++)
  {
   scanf("%d%d",&s,&e);
   b[s]+=1; b[e+1]-=1;
  }
  
  int sum=0;
  for(int i=1;i<=n;i++)
  {
   sum+=b[i];
   printf("%d ",sum);
  }
  printf("\n");
 }
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章