Color the ball
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6609 Accepted Submission(s): 3468
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,输入结束。
当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
思路:线段树题目,感觉是时候学学线段树这种数据结构了,于是找了一题练练,一次AC,爽啊!
成断更新,单点查询!
AC代码:
1 #include<stdio.h> 2 #define MAX 100001 3 typedef struct 4 { 5 int left; 6 int right; 7 int cover; 8 }Node; 9 Node ball[4*MAX]; 10 int cnt; 11 void build(int l,int r,int k) 12 { 13 int mid; 14 if(l == r) 15 { 16 ball[k].left = l; 17 ball[k].right = r; 18 ball[k].cover = 0; 19 return ; 20 } 21 ball[k].left = l; 22 ball[k].right = r; 23 ball[k].cover = 0; 24 mid = (l+r) >> 1; 25 build(l,mid,k << 1); 26 build(mid+1,r,k << 1|1); 27 } 28 29 void insert(int l,int r,int k) 30 { 31 if(l == ball[k].left && r == ball[k].right) 32 { 33 ball[k].cover++; 34 return ; 35 } 36 if(ball[k].right == ball[k].left) 37 return ; 38 int mid = (ball[k].left+ball[k].right) >> 1; 39 if(r <= mid) 40 insert(l,r,k << 1); 41 else if(l > mid) 42 insert(l,r,k << 1|1); 43 else 44 { 45 insert(l,mid,k << 1); 46 insert(mid+1,r,k << 1|1); 47 } 48 return ; 49 } 50 51 void search(int num,int k) 52 { 53 if(ball[k].left == ball[k].right) 54 { 55 cnt += ball[k].cover; 56 return ; 57 } 58 cnt += ball[k].cover; 59 int mid = (ball[k].left+ball[k].right) >> 1; 60 if(num <= mid) 61 search(num,k << 1); 62 else 63 search(num,k << 1|1); 64 return ; 65 } 66 67 int main() 68 { 69 int n,i; 70 int a,b; 71 while(~scanf("%d",&n) && n) 72 { 73 build(1,n,1); 74 for(i = 0;i < n;i ++) 75 { 76 scanf("%d%d",&a,&b); 77 insert(a,b,1); 78 } 79 for(i = 1;i < n;i ++) 80 { 81 cnt = 0; 82 search(i,1); 83 printf("%d ",cnt); 84 } 85 cnt = 0; 86 search(n,1); 87 printf("%d ",cnt); 88 } 89 return 0; 90 }