Color the ball
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 15145 Accepted Submission(s): 7540
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
Author
8600
Source
题意: 区间更新 单点查询
题解:
1.线段树 处理:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 #include<queue> 6 #include<stack> 7 using namespace std; 8 struct node 9 { 10 int l,r,value; 11 }tree[400005]; 12 int ans[100005]; 13 int n; 14 int aa,bb; 15 int jishu=0; 16 void buildtree(int root,int left,int right) 17 { 18 tree[root].l=left; 19 tree[root].r=right; 20 tree[root].value=0; 21 if(left==right) 22 return ; 23 int mid=(left+right)>>1; 24 buildtree(root<<1,left,mid); 25 buildtree(root<<1|1,mid+1,right); 26 } 27 void updata(int c,int left,int right,int root) 28 { 29 if(tree[root].l==left&&tree[root].r==right) 30 { 31 tree[root].value+=c; 32 return ; 33 } 34 int mid=(tree[root].l+tree[root].r)>>1; 35 if(right<=mid) 36 updata(c,left,right,root<<1); 37 else 38 { 39 if(left>mid) 40 updata(c,left,right,root<<1|1); 41 else 42 { 43 updata(c,left,mid,root<<1); 44 updata(c,mid+1,right,root<<1|1); 45 } 46 } 47 } 48 void sum(int root) 49 { 50 if(tree[root].l==tree[root].r) 51 { 52 ans[jishu]=tree[root].value; 53 jishu++; 54 return ; 55 } 56 tree[root<<1].value+=tree[root].value; 57 tree[root<<1|1].value+=tree[root].value; 58 sum(root<<1); 59 sum(root<<1|1); 60 } 61 int main() 62 { 63 while(scanf("%d",&n)!=EOF) 64 { 65 if(n==0) 66 break; 67 // memset(ans,0,sizeof(ans)); 68 buildtree(1,1,n); 69 for(int i=1;i<=n;i++) 70 { 71 scanf("%d %d",&aa,&bb); 72 updata(1,aa,bb,1); 73 } 74 jishu=1; 75 sum(1); 76 printf("%d",ans[1]); 77 for(int i=2;i<=n;i++) 78 printf(" %d",ans[i]); 79 printf("\n"); 80 } 81 return 0;
2.树状数组 处理
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int tree[1000005]; 6 int lowbit (int x) 7 { 8 return x&(-x); 9 } 10 void hsd (int a,int b,int c) 11 { 12 while(a<=c) 13 { 14 tree[a]+=b; 15 a+=lowbit(a); 16 } 17 } 18 int get(int x) 19 { int sum=0; 20 while(x>0) 21 { 22 sum+=tree[x]; 23 x-=lowbit(x); 24 } 25 return sum; 26 27 } 28 int main() 29 { 30 int n,i,a,b,x; 31 while(scanf("%d",&n)!=EOF) 32 { if(n==0) 33 break; 34 memset(tree,0,sizeof(tree)); 35 for(i=1; i<=n; i++) 36 { 37 scanf("%d%d",&a,&b); 38 hsd(a,1,n); 39 hsd(b+1,-1,n); 40 } 41 printf("%d",tree[1]); 42 for(i=2;i<=n;i++) 43 { 44 x=get(i); 45 printf(" %d",x); 46 } 47 cout<<endl; 48 49 } 50 return 0; 51 }
3. 区间更新姿势 处理
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 #include<queue> 6 #include<stack> 7 using namespace std; 8 int a[100005]; 9 int b[100005]; 10 int aa,bb; 11 int n; 12 int main() 13 { 14 while(scanf("%d",&n)!=EOF) 15 { 16 if(n==0) 17 break; 18 memset(a,0,sizeof(a)); 19 memset(b,0,sizeof(b)); 20 for(int i=1;i<=n;i++) 21 { 22 scanf("%d %d",&aa,&bb); 23 b[aa]++; 24 b[bb+1]--; 25 } 26 int q=0; 27 for(int i=1;i<=n;i++) 28 { 29 q+=b[i]; 30 a[i]=q; 31 } 32 printf("%d",a[1]); 33 for(int i=2;i<=n;i++) 34 printf(" %d",a[i]); 35 printf("\n"); 36 } 37 return 0; 38 }