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("%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