左偏树模板

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",&lt,&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

注:本对拍程序只检验了堆性质,并没有检验可并性质

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值