线段树(求单结点) hdu 1556 Color the ball

时间:2023-03-08 19:53:49

Color the ball

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 22122    Accepted Submission(s): 10715

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
Sample Output
1 1 1
3 2 1
Author
8600
Source
这道题目是每次每个点加一,不是区间问题
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define ls (u<<1)
#define rs (u<<1|1)
using namespace std; int ans[],n; struct node{
int l,r,n;
} node[]; void build(int u,int l,int r){
node[u].l = l;
node[u].r = r;
node[u].n = ;
if(l!=r){
int mid = (l+r)>>;
build(ls,l,mid);
build(rs,mid+,r);
}
} void update(int u,int x,int y){
if(node[u].l == x && node[u].r == y)//找到要刷的气球区间,更新其被刷的次数+1
node[u].n++;
else{
int mid = (node[u].l+node[u].r)>>;
if(y<=mid)
update(ls,x,y);
else if(x>mid)
update(rs,x,y);
else{
update(ls,x,mid);
update(rs,mid+,y);
}
}
} void query(int u){
for(int i = node[u].l; i<=node[u].r; i++)//该区间所有编号都被刷了一次
ans[i]+=node[u].n;//求单结点
if(node[u].l == node[u].r)
return;
query(ls);
query(rs);
} int main(){
int x,y;
while(cin >> n,n){
build(,,n);
for(int i = ; i<=n; i++){
cin >> x >> y;
update(,x,y);
}
memset(ans,,sizeof(ans));
query();
cout << ans[];
for(int i = ; i<=n; i++)
cout << " " << ans[i];
cout << endl;
}
return ;
}