主席树静态区间第K大模板

HJT.cpp

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1000000+10,maxr=maxn/5;
namespace HJT{
    int lch[maxn],rch[maxn],lst[maxn],rst[maxn];
    int sum[maxn],ncnt=0,root[maxr],a[maxn];
    void maintain(int t){
        sum[t]=sum[lch[t]]+sum[rch[t]];
    }
    void build_e(int t,int ls,int rs){
        if(ls==rs){
            lch[t]=rch[t]=0;
            lst[t]=rst[t]=ls;
            sum[t]=0;
        }else{
            int mid=(ls+rs)/2,nl=++ncnt,nr=++ncnt;
            build_e(nl,ls,mid);build_e(nr,mid+1,rs);
            lch[t]=nl;rch[t]=nr;
            lst[t]=ls;rst[t]=rs;sum[t]=0;
        }
    }
    void copy(int x,int y){
        lch[y]=lch[x];rch[y]=rch[x];
        lst[y]=lst[x];rst[y]=rst[x];
        sum[y]=sum[x];
    }
    void build(int lt,int rt,int ls,int rs,int v){
        copy(lt,rt);
        if(ls==rs){sum[rt]++;return;}
        int mid=(ls+rs)/2;
        if(v<=mid){
            lch[rt]=++ncnt;
            build(lch[lt],lch[rt],ls,mid,v);
        }else{
            rch[rt]=++ncnt;
            build(rch[lt],rch[rt],mid+1,rs,v);
        }
        maintain(rt);
    }
    void construct(int n,int mxv){
        root[0]=++ncnt;
        build_e(root[0],0,mxv);
        for(int i=1;i<=n;i++){
            root[i]=++ncnt;
            build(root[i-1],root[i],0,mxv,a[i]);
        }
    }
    int query(int lt,int rt,int k){
        if(sum[rt]-sum[lt]<k)return -1;
        if(lst[lt]==rst[lt])return lst[lt];
        int lsiz=sum[lch[rt]]-sum[lch[lt]];
        if(k<=lsiz){
            return query(lch[lt],lch[rt],k);
        }else return query(rch[lt],rch[rt],k-lsiz);
    }
}
int main(){
    int n,q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%d",&HJT::a[i]);
    HJT::construct(n,10000);
    for(int i=1;i<=q;i++){
        int l,r,k;scanf("%d%d%d",&l,&r,&k);
        //printf("\n [ %d, %d, %d, ] = %d. \n\n",l,r,k,
        //HJT::query(HJT::root[l-1],HJT::root[r],k));
        printf("%d\n",
        HJT::query(HJT::root[l-1],HJT::root[r],k));
    }
    return 0;
}

bforce.cpp 暴力程序

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int a[10000+10],tmp[100000+10];
int query(int L,int R,int k){
    memcpy(tmp,a,sizeof(tmp));
    sort(tmp+L,tmp+R+1);
    return tmp[L-1+k];
}
int main(){
    int n,q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=q;i++){
        int l,r,k;scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",query(l,r,k));
    }
    return 0;
}

data.cpp 数生成器

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int rand(int L,int R){
    return rand()%(R-L+1)+L;
}
#include<ctime>
int main(){
    srand(time(NULL));
    int n=rand(50,1000),q=rand(50,1000);
    printf("%d %d\n",n,q);
    for(int i=1;i<=n;i++)printf("%d ",rand(1,1000));
    putchar('\n');
    for(int i=1;i<=q;i++){
        int L=rand(1,n),R=rand(L,n),K=rand(1,R-L+1);
        printf("%d %d %d\n",L,R,K);
    }
    return 0;
}

try.bat 对拍程序

@echo off
set /a i=1
:begin
if %i% GTR 100 goto end
  data.exe   > input.txt
  HJT.exe    < input.txt > output.txt
  bforce.exe < input.txt > std.txt
  fc output.txt std.txt
  if errorlevel 1 pause
  set /a i=i+1
goto begin
:end
echo [end]
pause
阅读更多
版权声明:文章纯属版主手敲,请同学们尊重版主的知识产权。 https://blog.csdn.net/GGN_2015/article/details/78941654
个人分类: 数据结构
上一篇左偏树模板
下一篇ANSI C 线段树模板
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭