hdu_1556 Color the ball

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556

分析: 属于更新区间,找点类型的题。

       有树状数组,线段树两种方法,不用说也知道树状数组的简单些。

       树状数组,里面存的是一段区间的染色次数。属于向前更新,向后查找。

      线段树的话,节点里存有一段区间的染色次数,更新后,DFS一次得到每点的值。

我的代码(树状数组):

#include<stdio.h>
#include<string.h>
#define MAXN 100005
int C[MAXN];
int n;
int lowbit(int i)
{
    return i&(-i);
}
void updata(int i,int m)
{
    while(i>0)
    {
        C[i]+=m;
        i-=lowbit(i);
    }
}
int get_sum(int i)
{
    int sum=0;
    while(i<=n) {
        sum+=C[i];
        i+=lowbit(i);
    }
    return sum;
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        memset(C,0,sizeof(C));
       for(int i=0;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            updata( b,1);
            updata( a-1,-1); //[a,b] 为染的次数。
        }
        for(int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",get_sum(i));
    }
    return 0;
}

我的代码(线段树):

#include<stdio.h>
#include<string.h>
#define MAXN 100005
struct Node
{
    int l,r;
    int num;
}segtree[MAXN<<2];
void build(int i,int l,int r)
{
    segtree[i].l=l;
    segtree[i].r=r;
    segtree[i].num=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build( i*2, l, mid);
    build( i*2+1,mid+1, r);
}
void Modfiy(int i,int x,int y)//区间[a,b]段加1;
{
    //区间段的染色次数。
    if(x==segtree[i].l&&y==segtree[i].r)
    {
        segtree[i].num+=1;
        return ;
    }
    int mid=(segtree[i].l+segtree[i].r)>>1;
    if(y<=mid)
        Modfiy(i<<1,x, y);
    else if(x>mid)
        Modfiy(i<<1|1, x, y);
    else
    {
         Modfiy(i<<1,x, mid);
         Modfiy(i<<1|1, mid+1, y);
    }
}
int ans[MAXN];
void DFS(int i)
{
    for(int j=segtree[i].l;j<=segtree[i].r;j++) ans[j]+=segtree[i].num;
    if(segtree[i].l==segtree[i].r) return ;
    DFS( i<<1);
    DFS( i<<1|1);
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF&&n)
    {
        build(1,1,n);
        for(int i=0;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
             Modfiy(1,a,b);
        }
        memset(ans,0,sizeof(ans));
        DFS(1);
     //   printf("OK?\n");
        for(int i=1;i<=n;i++) printf(i!=n?"%d ":"%d\n",ans[i]);
    }


    return 0;
}

总结:还是树状数组的简单↖(^ω^)↗。。


今天再做这题的时候,数组直接复制了100000,果断WA了........o(>﹏<)o。——2013_9_9


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值