AC日记——手写堆ac合并果子(傻子)
今天整理最近的考试题
发现一个东西叫做优先队列
priority_queue(说白了就是大根堆)
但是
我对堆的了解还是很少的
所以
我决定手写一个堆
于是我写了一个简单的堆
手写的堆说白了就是个二叉树
能不更新维护的二叉树,每次维护的时间为logn
但是各种查询(empty,top什么的)时间为1;
感觉这个堆还写的像模像样
于是兴冲冲的去ac特别简单题合并果子
没a;
改了好久才ac
现在贴一下这个代码
来,上代码:
#include<cstdio> using namespace std; int heap[200000],num,jkl,cur,n,ans=0; char ch; void swap(int &a,int &b)//交换函数 { int t=a; a=b,b=t; } void qread(int &x)//读入优化 { x=0,jkl=1;ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-') jkl=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+(int)(ch-'0');ch=getchar();} x*=jkl; } void heap_up(int now)//向上维护(添加元素时) { if(now==1) return; int cnm=now/2; if(heap[cnm]>heap[now]) { swap(heap[cnm],heap[now]); heap_up(cnm); } } void heap_push(int kol)//添加元素同时维护 { num++; heap[num]=kol; if(num==1) return ; heap_up(num); } void heap_down(int now)//向下维护(删除元素时) { int l,r; if(now*2+1<=num) { l=now*2,r=now*2+1; if(heap[l]<heap[now]) { if(heap[r]<heap[l]) { swap(heap[r],heap[now]); heap_down(r); } else { swap(heap[l],heap[now]); heap_down(l); } } else { if(heap[r]<heap[now]) { swap(heap[r],heap[now]); heap_down(r); } } } else { if(now*2<=num) { l=now*2; if(heap[l]<heap[now]) swap(heap[l],heap[now]); } } } void heap_pop()//删除元素 { heap[1]=heap[num]; num--; heap_down(1); } int heap_top(){return heap[1];}//查询堆顶元素 bool heap_empty(){return num==0?true:false;}//查询是否为空 int main() { qread(n); for(int i=1;i<=n;i++) { qread(cur); heap_push(cur); } for(int i=1;i<n;i++) { cur=heap_top(); heap_pop(); cur+=heap_top(); heap_pop(); heap_push(cur); ans+=cur; } printf("%d\n",ans); return 0; }