zoukankan      html  css  js  c++  java
  • hdu4417

    题解:

    主席树,查找前y+1个,减去前x个

    当然也可以树状数组+离线

    细节注意处理(当h小于任何一个数和没有出现过的时候)

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=100005;
    int rt[N],a[N],n,t,z,m,b[N],x,cnt,now,y,k;
    struct Tree
    {
        int num,ls,rs;
    }T[20*N];
    int ef(int x)
    {
        int l=0,r=cnt;
        while (l<r)
         {
             int mid=(l+r+1)/2;
             if (b[mid]>x)r=mid-1;
             else l=mid;
         }
        return l; 
    }
    int build(int l,int r)
    {
        now++;
        if (l==r)return now;
        int k=now;
        int mid=(l+r)/2;
        if (l<=mid)T[k].ls=build(l,mid);
        if (mid<r)T[k].rs=build(mid+1,r);
        return k;
    }
    int insert(int x,int l,int r,int s)
    {
        now++;
        if (l==r)
         {
            T[now].num=T[x].num+1;
            return now;
         }
        int k=now,mid=(l+r)/2;
        if (s<=mid)
         {
             T[k].ls=insert(T[x].ls,l,mid,s);
             T[k].rs=T[x].rs;
         }
        else
         {
             T[k].ls=T[x].ls;
             T[k].rs=insert(T[x].rs,mid+1,r,s);
         }
        T[k].num=T[T[k].ls].num+T[T[k].rs].num;
        return k;
    }
    int find(int x,int y,int l,int r)
    {
        if (l==r)return l<=y?T[x].num:0;
        if (r<=y)return T[x].num;
        int mid=(l+r)/2,ans=find(T[x].ls,y,l,mid);
        if (mid<y&&mid!=r)ans+=find(T[x].rs,y,mid+1,r);
        return ans;
    }
    int main()
    {
        scanf("%d",&t);
        for (int cas=1;cas<=t;cas++)
         {
             printf("Case %d:
    ",cas);
             scanf("%d%d",&n,&m);
             memset(T,0,sizeof T);
             now=0;
             for (int i=1;i<=n;i++)scanf("%d",&a[i]);
             for (int i=1;i<=n;i++)b[i]=a[i];
             cnt=1;
             sort(b+1,b+n+1);
             for (int i=2;i<=n;i++)
              if (b[i-1]!=b[i])b[++cnt]=b[i];
             rt[0]=build(1,cnt);
            for (int i=1;i<=n;i++)rt[i]=insert(rt[i-1],1,cnt,ef(a[i])); 
             while (m--)
              {
                  scanf("%d%d%d",&x,&y,&z);
                  int k=ef(z);
                  if (k==0)puts("0");else 
                printf("%d
    ",find(rt[y+1],k,1,cnt)-find(rt[x],k,1,cnt));
              }
         }
    }
  • 相关阅读:
    【设计模式】模板模式
    【设计模式】适配器模式
    【设计模式】观察者模式
    【设计模式】原型模式
    【设计模式】建造模式
    【Android Studio】Android Studio 安装及设置
    【设计模式】工厂模式(静态工厂模式、工厂方法模式、抽象工厂模式)
    【Linux高级驱动】LCD logo
    【Linux高级驱动】LCD驱动框架分析
    【系统移植】JNI
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7905597.html
Copyright © 2011-2022 走看看