1. 程式人生 > >hdu1556 Color the ball (樹狀陣列應用型別二) 【區間更新 單點求值】

hdu1556 Color the ball (樹狀陣列應用型別二) 【區間更新 單點求值】

題目連線:http://acm.hdu.edu.cn/showproblem.php?pid=1556

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

分析:(參考大佬部落格 https://blog.csdn.net/yexiaohhjk/article/details/51077545

樹狀陣列不僅可以求單點更新區間求和,還可以求區間更新,單點求和。 
在單點更新裡面,樹狀陣列求和操作代表區間的和,而在區間更新中,樹狀陣列求和操作代表單個元素的變化量。

所以這題比如對(4,6)區間進行更新,就是update(4,1),update(6+1,-1), 
Query(i)代表查詢第i個數變化量。

程式碼:

#include<cstdio>
#include<cstring>
using namespace std;
const int N=100008;
int c[N];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int y)
{
    for(;x<=N;x+=lowbit(x))
    {
        c[x]+=y;
    }
}
int sum(int x)
{
    int ans=0;

    for(;x;x-=lowbit(x))
    {
        ans+=c[x];
    }
    return ans;
}
int main()
{
    int n;
  while(~scanf("%d",&n)&&n)
  {
      memset(c,0,sizeof(c));
      for(int i=1;i<=n;i++)
      {
          int a,b;
          scanf("%d%d",&a,&b);
          update(a,1);
          update(b+1,-1);
      }
      for(int i=1;i<=n-1;i++)
      {
          printf("%d ",sum(i));
      }
      printf("%d\n",sum(n));
  }
  return 0;
}