LUOGUP1631---序列合并
2017-12-14 16:42
232 查看
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n; int hp[1000005]; int z[1000000]; int cnt,acnt=1,bcnt=1; int a[100005],b[100005]; int mx; void pus(int x) {//建立大根堆(一直想的建个小根堆后来发现大根堆好用。。。) int now=++cnt; hp[now]=x; while(now>1) { int tp=now/2; if(hp[now]>hp[tp]) { swap(hp[now],hp[tp]); now=tp; } else break; } } int del() {//维护堆 int res=hp[1]; hp[1]=hp[cnt]; cnt--; int now=1; while(now*2<=cnt) { int tp=now*2; if(hp[tp+1]>hp[tp]&&tp<cnt)tp++; if(hp[tp]>hp[now])swap(hp[tp],hp[now]); else break; now=tp; } return res; } int main() { cin>>n; for( int i=1; i<=n; i++) { scanf("%d",&a[i]); } for(int i=1; i<=n; i++) scanf("%d",&b[i]); // memset(hp,0x7f,sizeof hp);//没有必要memset hp[1]=214512312; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { int r=a[i]+b[j]; if(r<hp[1]||cnt<n) { pus(r); if(cnt>n)del(); if(cnt==n&&a[i]+b[j+1]>=hp[1])break;//如果b的下一个+a现在的仍大于大根堆的第一个,就没必要继续进行下去了 } }if(cnt==n&&a[i+1]+b[1]>=hp[1])break;//同理 } int ans[100005]; for(int i=1; i<=n; i++) ans[i]=del(); for(int i=n;i>=1;i--)printf("%d ",ans[i]); }
一道堆排,然后主要是加了个好像是剪枝的东西。
然后先建起来一个大根堆,来判断是否能入堆。就这样。
相关文章推荐
- 刷题记录-luoguP1631 序列合并
- [luoguP1631] 序列合并(堆 || 优先队列)
- 序列合并 洛谷1631 堆
- 洛谷2085最小函数值(minval) + 洛谷1631序列合并
- 堆or优先队列(洛谷1631 序列合并)
- 洛谷 1631 序列合并 堆 解题报告
- 序列合并(luogu 1631)题解
- poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
- 两个有序链表序列的合并
- HYSBZ 1858(Scoi2010) 序列操作(线段树+区间合并)
- 浙江大学PAT上机题解析之2-11. 两个有序链表序列的合并
- STL中map的简单应用(合并表序列)
- 7-1 两个有序链表序列的合并
- 合并两个排序序列
- P1631 序列合并
- UVA 11996 Jewel Magic —— splay、序列的分裂与合并、LCP的哈希算法
- 关于priority_queue的运用(两道例题:序列合并 + 最小函数值)
- bzoj1858:序列操作 (线段树区间信息合并)
- 两个有序链表序列的合并
- luoguP1090合并果子