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; }