• hdu2665


    题解:

    裸的主席树,记录最小值

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=100005;
    int a[N],cnt,Case,rt[N],b[N],now,n,m,x,y,k;
    struct Tree
    {
        int ls,rs,num;
    }T[N*20];
    int ef(int x)
    {
        int l=1,r=cnt;
        while (l<r)
         {
             int mid=(l+r)/2;
             if (b[mid]<x)l=mid+1;
             else r=mid;
         }
        return l; 
    }
    int build(int l,int r)
    {
        now++;
        if (l==r)return now;
        int k=now,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 z,int l,int r)
    {
        if (l==r)return l;
        if (T[T[x].ls].num-T[T[y].ls].num>=z)
         return find(T[x].ls,T[y].ls,z,l,(l+r)/2);
        return find(T[x].rs,T[y].rs,z-
        T[T[x].ls].num+T[T[y].ls].num,(l+r)/2+1,r);
    }
    int main()
    {
        scanf("%d",&Case); 
        while (Case--)
         {
             memset(T,0,sizeof T);
             now=0;
             scanf("%d%d",&n,&m);
             for (int i=1;i<=n;i++)scanf("%d",&a[i]);
             for (int i=1;i<=n;i++)b[i]=a[i];
             sort(b+1,b+n+1);
             cnt=1;
             for (int i=2;i<=n;i++)
              if (b[i]!=b[i-1])b[++cnt]=b[i];
             for (int i=1;i<=n;i++)a[i]=ef(a[i]);
            rt[0]=build(1,n);
            for (int i=1;i<=n;i++)rt[i]=insert(rt[i-1],1,n,a[i]);
            while (m--)
             {
                 scanf("%d%d%d",&x,&y,&k);
                 printf("%d
    ",b[find(rt[y],rt[x-1],k,1,n)]);
             } 
         }
    }
  • 相关阅读:
    ORACLE触发器具体解释
    秒杀多线程第四篇 一个经典的多线程同步问题
    Java中Integer类的方法
    九大排序算法再总结
    删除条目时的确认对话框
    VirtualBox安装及使用说明和虚拟机安装XP系统图文教程
    J2EE之验证码实现
    教你用笔记本破解无线路由器password
    vSphere HA状况:未知配置错误解决的方法
    HDU 2504 又见GCD
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7900412.html
Copyright © 2020-2023  润新知