hdu 1556 color the balls


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


先附上自己的代码,虽然是超时,但毕竟是自己写的,现在的水平还是很low,不知道再怎么优化,不过后面有两种超赞的解法

#include<stdio.h>
#include<string.h>
#include <string>
#include <queue>
#include <iostream>
using namespace std;
typedef struct node{
    int l,r,value;
}temp;
 int n;
temp node[100000];
void init(int left,int right,int rt)
{
    node[rt].l=left;
    node[rt].r=right;
    node[rt].value=0;
    if (left==right)
        return;
    int mid=(left+right)>>1;
    init(left,mid,rt<<1);
    init(mid+1,right,rt<<1|1);
}
void update(int rt,int l,int r)
{
    if (node[rt].l==node[rt].r)
    {
        node[rt].value++;       //这些点都是父节点,到最后要输出子节点
        return;
    }
    int mid=(node[rt].l+node[rt].r)>>1;
    if (r<=mid)
        update(rt<<1,l,r);
    else if (l>mid)
        update(rt<<1|1,l,r);
    else
    {
            update(rt<<1,l,mid);
            update(rt<<1|1,mid+1,r);
    }
}
void out(int rt,int sum)
{
    if (node[rt].l==node[rt].r)
    {
        printf("%d",sum+node[rt].value);
        if (node[rt].l!=n)
            printf(" ");
        return ;
    }
    out(rt<<1,sum+node[rt].value);
    out(rt<<1|1,sum+node[rt].value);
}
int main()
{
    while (~scanf("%d",&n),n)
    {
        int i;
        init(1,n,1);
        int a,b;
        for (i=1;i<=n;i++)
        {
        scanf("%d%d",&a,&b);
        update(1,a,b);
        }
        out(1,0);
            printf("\n");
    }
    return 0;
}

看人家写的代码,真是一种享受,惊叹,感觉自己弱爆了,关于位运算还是没大了解

#include <stdio.h>  
#include <string.h>  
const int MAXN=110000;  
int n,c[MAXN];  
int lowbit(int x)  
//计算2^k  
{  
    x=x&-x;  
    return x;  
}  
void update(int num,int val)  
//向下查询,num是要更新的子节点,val是要修改的值  
{  
    while(num>0)  
    {  
        c[num]+=val;  
        num-=lowbit(num);  
    }  
}  
int getSum(int num)  
//向上统计每个区间被染色的次数  
{  
    int sum=0;  
    while(num<=n)  
    {  
        sum+=c[num];  
        num+=lowbit(num);  
    }  
    return sum;  
}  
int main()  
{  
    int a,b;  
    while(scanf("%d",&n),n)  
    {  
        memset(c,0,sizeof(c));  
        for(int i=0;i<n;i++)  
        {  
            scanf("%d%d",&a,&b);  
            //将b以下区间+1  
            update(b,1);  
            //将a以下区间-1  
            update(a-1,-1);  
        }  
        for(int j=1;j<n;j++)  
        {  
            printf("%d ",getSum(j));  
        }  
        printf("%d\n",getSum(n));  
    }  
    return 0;  
}  

这一篇跟我写的有点类似,但是人家用了数组来记录,自己没想起来

#include<iostream>  
using namespace std;  
struct node  
{  
    int left,right;  
    int sum,lnc;  
}tree[300000];  
int num[100000];  
void init(int id,int l,int r)  
{  
    if(l==r)  
    {  
        tree[id].sum=num[l];  
        tree[id].left=tree[id].right=l;  
        tree[id].lnc=0;  
        return ;  
    }  
    init(id*2,l,(l+r)/2);  
    init(id*2+1,(l+r)/2+1,r);  
    tree[id].sum=tree[2*id].sum+tree[id*2+1].sum;  
    tree[id].lnc=0;  
    tree[id].left=l;  
    tree[id].right=r;  
}  
void update(int id,int l,int r,int val)  
{  
    if(tree[id].left==l&&tree[id].right==r)  
    {  
        tree[id].lnc+=val;  
        return ;  
    }  
    tree[id].sum+=val*(r-l+1);  
    int mid=(tree[id].left+tree[id].right)/2;  
    if(r<=mid)  
        update(2*id,l,r,val);  
    else if(l>=mid+1)  
        update(2*id+1,l,r,val);  
    else  
    {  
        update(2*id,l,mid,val);  
        update(2*id+1,mid+1,r,val);  
    }  
}  
int read(int id,int l,int r)  
{  
    if(tree[id].left==l&&tree[id].right==r)  
    {  
        return tree[id].sum+tree[id].lnc*(r-l+1);  
    }  
    tree[id].sum+=tree[id].lnc*(tree[id].right-tree[id].left+1);  
    int val=tree[id].lnc;  
    int mid=(tree[id].left+tree[id].right)/2;  
    update(2*id,tree[id].left,mid,val);  
    update(2*id+1,mid+1,tree[id].right,val);  
    tree[id].lnc=0;  
    if(r<=mid)  
        return read(2*id,l,r);  
    else if(l>=mid+1)  
        return read(2*id+1,l,r);  
    else   
    {     
        return read(2*id,l,mid)+read(2*id+1,mid+1,r);  
    }  
}  
int main()  
{  
    int n,i,a,b,temp;  
    while(scanf("%d",&n)&&n)  
    {  
        memset(num,0,sizeof(num));  
        memset(tree,0,sizeof(tree));  
        init(1,1,n);  
        temp=n;  
          
        while(temp--)  
        {  
            scanf("%d%d",&a,&b);  
            update(1,a,b,1);  
        }  
        for(i=1;i<=n;i++)  
        {  
            printf("%d",read(1,i,i));  
            if(i!=n)  
                printf(" ");  
            else   
                printf("/n");  
        }  
    }  
    return 0;  
}  


你可能感兴趣的:(hdu 1556 color the balls)