Color the ball(树状数组+线段树+二分)

Color the ball

Time Limit : 9000/3000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 3   Accepted Submission(s) : 1
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
 

 

题解:线段树+树状数组,线段树用的很巧妙,少了lazy的麻烦;

树状数组代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<cstring>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int MAXN=100010;
10 int tree[MAXN+1];
11 int lowbit(int x){
12     return x&(-x);
13 }
14 void update(int x,int v){
15     while(x<=MAXN){
16         tree[x]+=v;
17         x+=lowbit(x);
18     }
19 }
20 int query(int x){
21     int temp=0;
22     while(x>0){
23         temp+=tree[x];
24         x-=lowbit(x);
25     }
26     return temp;
27 }
28 int main(){
29     int N,a,b;
30     while(~scanf("%d",&N),N){
31         memset(tree,0,sizeof(tree));
32         for(int i=0;i<N;i++){
33             scanf("%d%d",&a,&b);
34             update(a,1);
35             update(b+1,-1);
36         }
37         for(int i=1;i<=N;i++){
38             if(i-1)printf(" ");
39             printf("%d",query(i));
40         }
41         puts("");
42     }
43     return 0;
44 }

 线段树:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<cstring>
 7 #define L tree[root].l
 8 #define R tree[root].r
 9 #define S tree[root].sum
10 #define lson root<<1,l,mid
11 #define rson root<<1|1,mid+1,r 
12 using namespace std;
13 const int INF=0x3f3f3f3f;
14 const int MAXN=100010;
15 struct Node{
16     int l,r,sum;
17 };
18 Node tree[MAXN<<2];
19 int ans[MAXN];
20 void build(int root,int l,int r){
21     L=l;R=r;S=0;
22     if(l==r)return;
23     else{
24         int mid=(l+r)>>1;
25         build(lson);
26         build(rson);
27     }
28 }
29 void update(int root,int l,int r){
30     if(L==l&&R==r)S++;
31     else{
32         int mid=(L+R)>>1;
33         if(mid>=r)update(root<<1,l,r);
34         else if(mid<l)update(root<<1|1,l,r);
35         else{
36             update(lson);
37             update(rson);
38         }
39     }
40 }
41 void query(int root){
42     if(S){
43         for(int i=L;i<=R;i++)
44             ans[i]+=S;
45     }
46     if(L==R)return;
47     query(root<<1);query(root<<1|1);
48 }
49 int main(){
50     int N,a,b;
51     while(~scanf("%d",&N),N){
52         build(1,1,N);
53         memset(ans,0,sizeof(ans));
54         for(int i=0;i<N;i++){
55             scanf("%d%d",&a,&b);
56             update(1,a,b);
57         }
58         query(1);
59         for(int i=1;i<=N;i++){
60             if(i-1)printf(" ");
61             printf("%d",ans[i]);
62         }puts("");
63     }
64     return 0;
65 }

 以前二分水过一次:贴下吧

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1);
#define mem(x,y) memset(x,y,sizeof(x))
const int MAXN=1e5+100;
int s[MAXN],e[MAXN];
int main(){
    int N;
    while(scanf("%d",&N),N){
        for(int i=0;i<N;i++){
            scanf("%d%d",&s[i],&e[i]);
        }
        sort(s,s+N);sort(e,e+N);
        int q;
        for(int i=1;i<=N;i++){
            q=i;
            int x=upper_bound(s,s+N,q)-s;
            int y=lower_bound(e,e+N,q)-e;
            if(i!=1)printf(" ");
            printf("%d",x-y);
            if(i==N)puts("");
        }
    }
    return 0;
}

  

posted @ 2015-10-27 21:39  handsomecui  阅读(432)  评论(0编辑  收藏  举报