HDU1556

利用线段树,,用做模板!

#include<stdio.h>
#include<string.h>
#define MAXN 100005
struct ST //存储类型
{
    int l,r,num; //max表示当前节点的最大值
}st[4*MAXN];
int ans[MAXN];
void build(int ll,int rr,int n) //初始化建立线段树
{
    st[n].l=ll;   //表示当前节点的最左端,
    st[n].r=rr;   //表示当前节点的最右端,
    st[n].num=0;  //当前节点的值,初始化全为零,
    if (ll==rr) return ; //如果遇到了根节点
    int mid=(ll+rr)>>1;   //将当前节点分开,mid为左孩子的右端点,为右孩子的左端点;
    build(ll,mid,2*n);  //先遍历左边的树
    build(mid+1,rr,2*n+1); //再遍历右边的树
}
void insert(int ll,int rr,int n)  // 更新
{
    if (st[n].l==ll&&st[n].r==rr)
        st[n].num++;//表示区间的值,即这个区间的值都加一,在后面加
        else
        {
            int mid=(st[n].l+st[n].r)>>1;
            if (rr<=mid) //如果右端点比他的中间区分值mid还小,那么久插到左边,
                insert(ll,rr,2*n);
            else if (ll>=mid+1)   //如果左端点比他的中间区分值mid还大,那么久插到右边,
               insert(ll,rr,2*n+1);
            else
            {  //表示中间分开的
                insert(ll,mid,2*n);
                insert(mid+1,rr,2*n+1);
            }
        }

}
 void fin(int x)
 {
     for(int i=st[x].l;i<=st[x].r;i++)
        ans[i]+=st[x].num; //更新区间的值;
     if(st[x].l==st[x].r)
        return ;
     fin(2*x);  //再查找左边的结点
     fin(2*x+1); //右边的节点;
 }
int main()
{
    int n,m,a,b,i;
    while (scanf("%d",&n)!=EOF&&n)
    {
        build(1,n,1);
         memset(ans,0,sizeof(ans));
        for (i=1;i<=n;++i)
        {
            scanf("%d %d",&a,&b);
            insert(a,b,1);
        }
        fin(1);
        printf("%d",ans[1]);
        for (i=2;i<=n;++i)
        {
            printf(" %d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值