hdu-4417-Super Mario

//一个考数据结构的题,我用线段树做的,先分层分区间排序,后面对目的区间的里的数二分找就是可以了,这个题型,在刘汝佳的题里面出现过,而且这里只需查找,不要更新,所以就更容易解了,这题解法有很多,划分树+二分,我想也能解吧;

//线段树+二分代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct node
{
    int d[110000];
}td[22];
int find(int dep,int l,int r,int v)
{
    int mid,start=l,end=r;
    if(td[dep].d[l]>v)return 0;
    else if(td[dep].d[r]<=v)return r-l+1;
    while(1)
    {
        mid=(start+end)>>1;
        if(start==mid)break;
        if(td[dep].d[mid]>v)
        {
            end=mid-1;
            if(td[dep].d[end]<=v)
                return end-l+1;
        }
        else start=mid;
    }
    if(td[dep].d[mid]>v)mid--;
    return mid-l+1;
}
void build(int dep,int l,int r)
{
    int j,mid;
    for(j=l;j<=r;j++)
        td[dep].d[j]=td[dep-1].d[j];
    if(l==r)
        return ;
    else 
    {
        mid=(l+r)>>1;
        build(dep+1,l,mid);
        build(dep+1,mid+1,r);
        sort(td[dep].d+l,td[dep].d+r+1);
    }
}
int query(int dep,int l,int r,int a,int b,int v)
{
    int mid;
    if(a==l&&b==r)
        return find(dep,l,r,v);
    else 
    {
        mid=(l+r)>>1;
        if(b<=mid)
            return query(dep+1,l,mid,a,b,v);
        else if(b>mid&&a<=mid)
            return query(dep+1,l,mid,a,mid,v)+query(dep+1,mid+1,r,mid+1,b,v);
        else return query(dep+1,mid+1,r,a,b,v);
    }
}
int main()
{
    int n,m,i,l,r,h,cass,cas;
    scanf("%d",&cass);
    for(cas=1;cas<=cass;cas++)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%d",&td[0].d[i]);
        build(1,1,n);
        printf("Case %d:\n",cas);
        while(m--)
        {
            scanf("%d%d%d",&l,&r,&h);
            printf("%d\n",query(1,1,n,l+1,r+1,h));
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值