mheap.cpp
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn (1000000+10)
#define maxr (1000+10)
int _tab=0;
void tab(){
for(int i=1;i<=_tab;i++)printf(" ");
}
namespace Mheap{
int lch[maxn],rch[maxn],k[maxn];
int d[maxn],ncnt,root[maxr];//d:最多向右走多远
void maintain(int t){//maintain计算d
d[t]=d[rch[t]]+1;
}
void insert(int& t,int x){//传引用
if(t==0){
t=++ncnt;
lch[t]=rch[t]=0;k[t]=x;
maintain(t);//=1
}else{
if(x>k[t])swap(x,k[t]);
insert(rch[t],x);
if(d[lch[t]]<d[rch[t]])//左偏性质
swap(lch[t],rch[t]);
maintain(t);//lch+rch
}
}
int top(int t){return k[t];}
void merge(int& lt,int& rt){
if(lt==0){lt=rt;rt=0;return;}
if(rt==0){return;}
if(k[lt]<k[rt])swap(lt,rt);
merge(rch[lt],rt);
if(d[lch[lt]]<d[rch[lt]])
swap(lch[lt],rch[lt]);
maintain(lt);
}
void pop(int& t){
if(t==0)return;
merge(lch[t],rch[t]);t=lch[t];
}
void debugT(int t){
if(t==0){
tab();printf("{}\n");
return;
}
tab();printf("[%d] %d\n",t,k[t]);
tab();printf("{\n");_tab++;
debugT(lch[t]);debugT(rch[t]);
_tab--;tab();printf("}\n");
}
void debugA(){
for(;;){
int op;scanf("%d",&op);
if(op==1){
int r,x;scanf("%d%d",&r,&x);
insert(root[r],x);
}else if(op==2){
int lt,rt;scanf("%d%d",<,&rt);
merge(root[lt],root[rt]);
}else if(op==3){
int t;scanf("%d",&t);
debugT(root[t]);
}else if(op==4){
int r;scanf("%d",&r);
printf("\n mx [ %d. ] = %d. \n\n",r,top(root[r]));
}else if(op==5){
int r;scanf("%d",&r);
pop(root[r]);
}
printf("\n OK. \n\n");
}
}
void heapTest(){
int n;scanf("%d",&n);
for(int q=1;q<=n;q++){
int op;scanf("%d",&op);
if(op==1){//push
int x;scanf("%d",&x);
insert(root[1],x);
}else if(op==2){//top
printf("%d\n",top(root[1]));
}else if(op==3){//pop
pop(root[1]);
}
}
}
}
#undef maxr
#undef maxn
int main(){
//Mheap::debugA();
Mheap::heapTest();
return 0;
}
pq.cpp STL中的优先队列
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
priority_queue<int>PQ;
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
int op;scanf("%d",&op);
if(op==1){
int x;scanf("%d",&x);
PQ.push(x);
}else if(op==2){
printf("%d\n",PQ.top());
}else if(op==3){
if(!PQ.empty())PQ.pop();
}
}
return 0;
}
data.cpp 数据生成器
#include<cstdio>
#include<cstdlib>
#include<ctime>
using namespace std;
int rand(int L,int R){return rand()%(R-L+1)+L;}
int cnt=0;
int main(){
srand(time(NULL));
int n=rand(200,1000);printf("%d\n",n);
int lsop=-1;
for(int i=1;i<=n;i++){
int op=cnt==0?1:(lsop!=2?rand(1,3):rand(1,2)*2-1);
printf("%d",op);
if(op==1)printf(" %d",rand(1,10000)),cnt++;
if(op==3)cnt--;
putchar('\n');
lsop=op;
}
return 0;
}
try.bat 对拍程序
@echo off
set /a i=1
:begin
if %i% GTR 100 goto end
data.exe > input.txt
pq.exe < input.txt > std.txt
mheap.exe < input.txt > output.txt
fc std.txt output.txt
if errorlevel 1 pause
set /a i=i+1
goto begin
:end
echo end!
pause
注:本对拍程序只检验了堆性质,并没有检验可并性质