HDU4417 Super Mario

http://acm.hdu.edu.cn/showproblem.php?pid=4417


2012hangzhouonline

给出一个大小 n 的数组,m 组操作,(n,m < = 10 w ). 每组操作是3个数,L,R,H ,求数组区间[L,R]中小于等于H的数有多少个?


先将输入数据按数值大小排序,包括查询的数据。然后对排序后的数据除查询数据外按次序插入,插入位置即为原在数组中的位置,由于前面插入的数据必然不大于要查询数据,故每次查询统计某段区间元素个数即可。线段树或树状数组。


#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
//#include <vector>
#include <iostream>
#include <algorithm>
#include<string>
using namespace std;
//const double ePs=1e-7;
//const double INF=1e50;
//const double Pi=acos(-1);

#define NN 131072
#define INF 0x7ffffff
#define N 100005

struct data
{
    int d;
    bool f;
    int s,t;
    int num;
}a[2*N];

struct tree
{
    int s,t,sum;
}t[NN*2+5];

int n,s,c[N];

bool cmp(const data &a1,const data &b)
{
    if (a1.d!=b.d) return a1.d<b.d;
    else return a1.f;
}

void build(int m,int p,int q)
{
    t[m].s=p;
    t[m].t=q;
    t[m].sum=0;

    if (m<NN)
    {
        int mid=(p+q)/2;
        build(2*m,p,mid);
        build(2*m+1,mid+1,q);
    }
}

void Update(int m)
{
    while (m>0)
    {
        t[m].sum++;
        m/=2;
    }
}

void Insert(int m)
{
    t[m+NN-1].sum++;
    Update((m+NN-1)/2);
}

void Query(int m,int p,int q)
{
    if (t[m].s==p && t[m].t==q)
    {
        s+=t[m].sum;
        return ;
    }

    if (q<=t[2*m].t) Query(2*m,p,q);
    else if (p>=t[2*m+1].s) Query(2*m+1,p,q);
    else
    {
        Query(2*m,p,t[2*m].t);
        Query(2*m+1,t[2*m+1].s,q);
    }
}

int main()
{
    //freopen("a","r",stdin);

    int T,kk,m,i;
    scanf("%d",&T);
    for (kk=1;kk<=T;kk++)
    {
        printf("Case %d:\n",kk);

        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++)
        {
            scanf("%d",&a[i].d);
            a[i].s=i;
            a[i].f=true;
        }

        for (i=n+1;i<=n+m;i++)
        {
            scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].d);
            a[i].s++;
            a[i].t++;
            a[i].f=false;
            a[i].num=i-n;
        }

        sort(a+1,a+n+m+1,cmp);
        build(1,1,NN);

        for (i=1;i<=n+m;i++)
        if (a[i].f) Insert(a[i].s);
        else
        {
            s=0;
            Query(1,a[i].s,a[i].t);
            c[a[i].num]=s;
        }

        for (i=1;i<=m;i++) printf("%d\n",c[i]);
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
//#include <vector>
#include <iostream>
#include <algorithm>
#include<string>
using namespace std;
//const double ePs=1e-7;
//const double INF=1e50;
//const double Pi=acos(-1);

#define NN 131072
#define INF 0x7ffffff
#define N 100005

struct data
{
    int d;
    bool f;
    int s,t;
    int num;
}a[2*N];

int t[N];

int n,s,c[N];

bool cmp(const data &a1,const data &b)
{
    if (a1.d!=b.d) return a1.d<b.d;
    else return a1.f;
}

void Add(int p,int d)
{
    while (p<=n)
    {
        t[p]+=d;
        p+=p&(-p);
    }
}

int sum(int p)
{
    int ret=0;
    while (p)
    {
        ret+=t[p];
        p-=p&(-p);
    }

    return ret;
}

int main()
{
    //freopen("a","r",stdin);

    int T,kk,m,i;
    scanf("%d",&T);
    for (kk=1;kk<=T;kk++)
    {
        printf("Case %d:\n",kk);

        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++)
        {
            scanf("%d",&a[i].d);
            a[i].s=i;
            a[i].f=true;
        }

        for (i=n+1;i<=n+m;i++)
        {
            scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].d);
            a[i].s++;
            a[i].t++;
            a[i].f=false;
            a[i].num=i-n;
        }

        sort(a+1,a+n+m+1,cmp);

        for (i=0;i<=n;i++) t[i]=0;
        for (i=1;i<=n+m;i++)
        if (a[i].f) Add(a[i].s,1);
        else c[a[i].num]=sum(a[i].t)-sum(a[i].s-1);

        for (i=1;i<=m;i++) printf("%d\n",c[i]);
    }

    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值