堆的应用

来源:互联网 发布:仓库管理系统网页源码 编辑:程序博客网 时间:2024/06/05 18:35

链接:C++中的堆和栈
这篇博客是讲堆的几种定义

题目

洛谷 P3817 中位数

洛谷 P1168 中位数

P1168代码

STL版本

#include<cstdio>#include<iostream>#include<queue>#include<algorithm>using namespace std;int n,a1;priority_queue<int,vector<int> ,greater<int> >minheap;//小根堆 priority_queue<int>maxheap;//大根堆 inline int read(){    int x=0,w=1;char ch=0;    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();    return x*w;}int main() {    n=read();a1=read();     printf("%d\n",a1);    minheap.push(a1);    for(int i=1; i<=(n-1)/2; i++) {        int a,b;        a=read();b=read();        if(a<minheap.top()) { maxheap.push(a);} else { minheap.push(a);}        if(b<minheap.top()) { maxheap.push(b);} else { minheap.push(b);}        while(maxheap.size()>=minheap.size()) { minheap.push(maxheap.top()); maxheap.pop();}        while(maxheap.size()<minheap.size()-1) {maxheap.push(minheap.top());minheap.pop();}        printf("%d\n",minheap.top());    }    return 0;}

手动模拟堆(不过有点长)

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define fp(i,a,b) for(register int i=a;i<=b;++i)using namespace std;int n,t1,t2,size1,size2,mid;int big[400005],small[400005];//首先,想想为什么可以用 inline int read(){    int x=0,w=1;char ch=0;    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();    return x*w;}inline void big_put(int x){    big[++size2]=x;    int now=size2,next;    while(now>1){        next=now>>1;        if(big[now]<=big[next]) return;        swap(big[now],big[next]);        now=next;    }}inline int big_get(){    int now=1,next,v=big[1];    big[1]=big[size2--];    while(now<<1<=size2){        next=now<<1;        if(next<size2&&big[next+1]>big[next]) ++next;        if(big[now]>=big[next]) break;        swap(big[next],big[now]);        now=next;    }    return v;}inline void small_put(int x){    small[++size1]=x;    int now=size1,next;    while(now>1){        next=now>>1;        if(small[now]>=small[next]) return;        swap(small[now],small[next]);        now=next;    }}inline int small_get(){    int now=1,next,v=small[1];    small[1]=small[size1--];    while(now<<1<=size1){        next=now<<1;        if(next<size1&&small[next+1]<small[next]) ++next;        if(small[now]<=small[next]) break;        swap(small[next],small[now]);        now=next;    }    return v;}int main(){    n=read();t1=read();    big_put(t1);printf("%d\n",mid=t1);    for(register int i=1;i<<1<n;++i){        t1=read();t2=read();        if(t1>mid) small_put(t1);else big_put(t1);        if(t2>mid) small_put(t2);else big_put(t2);        if(size1>=size2) big_put(small_get());        if(size1+1<size2) small_put(big_get());        printf("%d\n",mid=big[1]);    }    return 0;}

P3387代码

STL版本

#include<cstdio>#include<iostream>#include<queue>#include<algorithm>using namespace std;int n,m,mid;char s[10];priority_queue<int,vector<int> ,greater<int> >minheap;//小根堆 priority_queue<int>maxheap;//大根堆 inline int read(){    int x=0,w=1;char ch=0;    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();    return x*w;}int main() {    n=read();    for(register int i=1; i<=n; ++i) {        int a;        a=read();        if(a>mid) { minheap.push(a);} else { maxheap.push(a);}        while(minheap.size()>=maxheap.size()) { maxheap.push(minheap.top()); minheap.pop();}        while(minheap.size()+1<maxheap.size()) {minheap.push(maxheap.top());maxheap.pop();}    }    m=read();    for(register int i=1;i<=m;++i){        int a;        cin>>s;        if(s[0]=='a'){        a=read();        if(a>mid) { minheap.push(a);} else { maxheap.push(a);}        while(minheap.size()>=maxheap.size()) { maxheap.push(minheap.top()); minheap.pop();}        while(minheap.size()+1<maxheap.size()) {minheap.push(maxheap.top());maxheap.pop();}        }        else printf("%d\n",mid=maxheap.top());    }    return 0;}

手动模拟版本

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define fp(i,a,b) for(register int i=a;i<=b;++i)using namespace std;int n,t1,t2,size1,size2,mid,m;int big[400005],small[400005];char s[10];inline int read(){    int x=0,w=1;char ch=0;    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();    return x*w;}inline void big_put(int x){    big[++size2]=x;    int now=size2,next;    while(now>1){        next=now>>1;        if(big[now]<=big[next]) return;        swap(big[now],big[next]);        now=next;    }}inline int big_get(){    int now=1,next,v=big[1];    big[1]=big[size2--];    while(now<<1<=size2){        next=now<<1;        if(next<size2&&big[next+1]>big[next]) ++next;        if(big[now]>=big[next]) break;        swap(big[next],big[now]);        now=next;    }    return v;}inline void small_put(int x){    small[++size1]=x;    int now=size1,next;    while(now>1){        next=now>>1;        if(small[now]>=small[next]) return;        swap(small[now],small[next]);        now=next;    }}inline int small_get(){    int now=1,next,v=small[1];    small[1]=small[size1--];    while(now<<1<=size1){        next=now<<1;        if(next<size1&&small[next+1]<small[next]) ++next;        if(small[now]<=small[next]) break;        swap(small[next],small[now]);        now=next;    }    return v;}int main(){    n=read();    for(register int i=1;i<=n;++i){        t1=read();        if(t1>mid) small_put(t1);else big_put(t1);        if(size1>=size2) big_put(small_get());        if(size1+1<size2) small_put(big_get());    }    m=read();    for(register int i=1;i<=m;++i){        cin>>s;        if(s[0]=='a') {            t1=read();            if(t1>mid) small_put(t1);else big_put(t1);            if(size1>=size2) big_put(small_get());            if(size1+1<size2) small_put(big_get());        }         if(s[0]=='m') printf("%d\n",mid=big[1]);    }    return 0;}
原创粉丝点击