HDOJ Color the ball (线段树方法)

 

Color the ball

Time Limit : 9000/3000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 5   Accepted Submission(s) : 3
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

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<iostream>
using namespace std;
const int maxn=300000;
struct segtree{
       int left,right,key;
}t[maxn];
void build(int l,int r,int dex){ 
    t[dex].left=l,t[dex].right=r,t[dex].key=0;
    if(l==r)
         return ;
    int mid=(l+r)/2;
    build(l,mid,dex*2);
    build(mid+1,r,dex*2+1);
}
void updata(int l,int r,int dex){
     int mid=(t[dex].left+t[dex].right)/2;
     if(t[dex].left==l && t[dex].right==r)
           t[dex].key++ ;
     else if(r<=mid)
           updata(l,r,dex*2);
     else if(l>mid)
           updata(l,r,dex*2+1);
     else
           updata(l,mid,dex*2),updata(mid+1,r,dex*2+1);
}
int query(int l,int r,int dex){
    int mid=(t[dex].left+t[dex].right)/2;
    if(t[dex].left==l && t[dex].right==r)
         return t[dex].key;
    int sum=0;
    if(l>=t[dex].left && r<=t[dex].right){
             sum+=t[dex].key;
             if(r<=mid)
                  sum+=query(l,r,dex*2);
             else if(l>mid)
                  sum+=query(l,r,dex*2+1);
             else
                  sum=sum+query(1,mid,dex*2)+query(mid+1,r,dex*2+1);
    }
    return sum;
}
int main(){
    int n,a,b;
    while(scanf("%d",&n)!=EOF && n){
         build(1,n,1);
         for(int i=1;i<=n;i++){
              scanf("%d%d",&a,&b);
              updata(a,b,1);
         }
         for(int i=1;i<n;i++)
         printf("%d ",query(i,i,1));
         printf("%d\n",query(n,n,1));
    }
    return 0;
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值