Color the ball
Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 30 Accepted Submission(s) : 13
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
Author
8600
Source
HDU 2006-12 Programming Contest
线段树的基础题,需要对区间的一次更新:
#include <stdio.h> #include <stdlib.h>struct Line {int Left,Right;int Max; }; struct Line ID[600000]; int Len; void Build(int l,int r,int n) {int Mid=(l+r)/2;ID[n].Left=l;ID[n].Right=r;ID[n].Max=0;if (l==r) return;Build(l,Mid,2*n);Build(Mid+1,r,2*n+1); }void Ouput(int l,int r,int n,int sum) {int Mid=(l+r)/2;if(ID[n].Left==ID[n].Right){printf("%d",sum+ID[n].Max);if(ID[n].Left!=Len)putchar(' ');return;}if(ID[n].Max!=0){Ouput(l,Mid,2*n,sum+ID[n].Max);Ouput(Mid+1,r,2*n+1,sum+ID[n].Max);}else{Ouput(l,Mid,2*n,sum);Ouput(Mid+1,r,2*n+1,sum);}}void Search(int r,int l,int Step) {int Mid;if (r==ID[Step].Left && l==ID[Step].Right){ID[Step].Max++;return;}Mid=(ID[Step].Left+ID[Step].Right)/2;if (Mid>=l) Search(r,l,Step*2);else if (Mid<r) Search(r,l,Step*2+1);else{Search(r,Mid,Step*2);Search(Mid+1,l,Step*2+1);} }int main() {int N,a,b,T;while(scanf("%d",&N)!=EOF){if(N==0)break;T=N,Len=N;Build(1,N,1);while(T--){scanf("%d%d",&a,&b);Search(a,b,1);}Ouput(1,N,1,0);putchar('\n');}return 0; }
修改:2015.5.15
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 typedef struct Line 7 { 8 int Left,Right; 9 int Key;/*关键值*/ 10 int Times;/*计数器*/ 11 }LR; 12 LR ID[1008600];/*每一个节点都需要一个存储*/ 13 int Len; 14 15 void Build(int L,int R,int n) /*输入时建立二叉树根*/ 16 { 17 int Mid=(L+R)/2; 18 ID[n].Left=L;ID[n].Right=R; 19 ID[n].Key=0;ID[n].Times=0;/*初始化为0*/ 20 if (L==R)return; /*找到根节点的时候结束*/ 21 Build(L,Mid,2*n); 22 Build(Mid+1,R,2*n+1); 23 } 24 void Search(int L,int R,int Step)/*匹配区间*/ 25 { 26 int Mid; 27 if(L==ID[Step].Left && R==ID[Step].Right) 28 {ID[Step].Times++;return;}/*记录累计次数*/ 29 Mid=(ID[Step].Left+ID[Step].Right)/2; 30 if (Mid>=R) Search(L,R,Step*2); 31 else if (Mid<L) Search(L,R,Step*2+1); 32 else 33 { 34 Search(L,Mid,Step*2); 35 Search(Mid+1,R,Step*2+1); 36 } 37 } 38 void UpData_S(int L,int R,int Step,int sum)/*一步更新*/ 39 { /*初始化为UpData_S(1,N,1,0);*/ 40 int Mid; 41 if(L==R) 42 { 43 ID[Step].Key=sum+ID[Step].Times;/*单点求和*/ 44 printf("%d",ID[Step].Key);/*输出该点的关键值*/ 45 if(L!=Len)putchar(' '); 46 else putchar(10); 47 return ; 48 } 49 Mid=(ID[Step].Left+ID[Step].Right)/2; 50 UpData_S(L,Mid,Step*2,sum+ID[Step].Times); 51 UpData_S(Mid+1,R,Step*2+1,sum+ID[Step].Times); 52 } 53 int main() 54 { 55 int N,i,a,b; 56 while(scanf("%d",&N)&&N)/*输入N,表示1~N区间*/ 57 { 58 Len=N; 59 Build(1,N,1); 60 for(i=0;i<N;i++) 61 { 62 scanf("%d%d",&a,&b); 63 Search(a,b,1);/*对区间[a,b]计数器++*/ 64 } 65 UpData_S(1,N,1,0);/*一步更新所有关键值*/ 66 } 67 return 0; 68 }
更新模板:2016.4.14
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define MaxN 1008600 6 using namespace std; 7 int Len; 8 struct Node{int L,R,Key,Add;}ID[MaxN];/*每一个节点都需要一个存储*/ 9 void Down_Date(int n){/*向下更新*/ 10 if(ID[n].Add!=0){ 11 ID[2*n].Add+=ID[n].Add; 12 ID[2*n+1].Add+=ID[n].Add; 13 ID[n].Key+=(ID[n].R-ID[n].L+1)*ID[n].Add; 14 ID[n].Add=0; 15 } 16 } 17 void Build(int L,int R,int n)/*输入时建立二叉树根,Build(1,N,1)*/ 18 { 19 ID[n].L=L;ID[n].R=R; 20 ID[n].Add=0;ID[n].Key=0; 21 if (L==R){return;} 22 int Mid=(L+R)/2; 23 Build(L,Mid,2*n);Build(Mid+1,R,2*n+1); 24 } 25 26 void UpDate_L(int L,int R,int n,int v)/*区间更新,区间加减*/ 27 { 28 if(L==ID[n].L && R==ID[n].R){ 29 ID[n].Add+=v;return ; 30 } 31 ID[n].Key+=v*(R-L+1);/*不匹配区间的时候,直接改变关键值*/ 32 Down_Date(n);/*可以每次更新,提高效率*/ 33 int Mid=(ID[n].L+ID[n].R)/2; 34 if (Mid>=R) UpDate_L(L,R,n*2,v); 35 else if (Mid<L) UpDate_L(L,R,n*2+1,v); 36 else{ 37 UpDate_L(L,Mid,n*2,v); 38 UpDate_L(Mid+1,R,n*2+1,v); 39 } 40 } 41 42 void Query_All(int L,int R,int n)/*询问所有点*/ 43 { 44 if(L==R){ 45 printf("%d",ID[n].Key+ID[n].Add); 46 if(L==Len)putchar(10); 47 else putchar(32); 48 return ; 49 } 50 Down_Date(n); 51 int Mid=(ID[n].L+ID[n].R)/2; 52 if (Mid>=R) Query_All(L,R,n*2); 53 else if (Mid<L) Query_All(L,R,n*2+1); 54 else{ 55 Query_All(L,Mid,n*2); 56 Query_All(Mid+1,R,n*2+1); 57 } 58 } 59 60 int main() 61 { 62 char Str; 63 int T,t=1,N,M,A,B,i; 64 while(scanf("%d",&N)&&N) 65 { 66 Build(1,N,1);Len=N; 67 for(i=0;i<N;i++){ 68 scanf("%d%d",&A,&B); 69 UpDate_L(A,B,1,1); 70 } 71 Query_All(1,N,1); 72 } 73 return 0; 74 }