hdu1556 Color the ball (樹狀陣列應用型別二) 【區間更新 單點求值】
阿新 • • 發佈:2019-01-11
題目連線: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)。
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; }