赞
踩
STL 中关于堆的操作会在后续会补充。
题目描述
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。
输入格式
第一行包含整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
输出格式
共一行,包含 m 个整数,表示整数数列中前 m 小的数。
数据范围
1 ≤ m ≤ n ≤ 1e5
1 ≤ 数列中元素 ≤ 1e9
输入样例
5 3
4 5 1 3 2
输出样例
1 2 3
#include <bits/stdc++.h> using namespace std; const int N=100010; int n,m; int h[N],ssize; void down(int u)//比较三个数当中的最小值 { int t=u; //左子节点 (左子节点存在且左子节点小于父节点) if(u*2 <= ssize && h[u*2]<h[t]) { t=u*2; } //右子节点 (右子节点存在且右子节点小于父节点) if(u*2+1 <= ssize && h[u*2+1]<h[t]) { t=u*2+1; } if(u!=t) { swap(h[u],h[t]); down(t); } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>h[i]; } ssize=n; for(int i=n/2;i!=0;i--) { down(i); } while(m--) { cout<<h[1]<<" "; h[1]=h[ssize]; ssize--; down(1); } system("pause"); return 0; }
题目描述
维护一个集合,初始时集合为空,支持如下几种操作:
I x
,插入一个数 x。PM
,输出当前集合中的最小值。DM
,删除当前集合中的最小值(数据保证此时的最小值唯一)。D k
,删除第 k 个插入的数。C k x
,修改第 k 个插入的数,将其变为 x。现在要进行 N 次操作,对于所有第 2 个操作,输出当前集合的最小值。
输入格式
第一行包含整数 N。
接下来 N 行,每行包含一个操作指令,操作指令为 I x
,PM
,DM
,D k
或 C k x
中的一种。
输出格式
对于每个输出指令 PM
,输出一个结果,表示当前集合中的最小值。
每个结果占一行。
数据范围
1 ≤ N ≤ 1e5
−1e9 ≤ x ≤ 1e9
数据保证合法。
输入样例
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM
输出样例
-10
6
#include <bits/stdc++.h> using namespace std; const int N = 100010; int h[N],cnt; int ph[N],hp[N]; void heap_swap(int a,int b) { swap(ph[hp[a]],ph[hp[b]]); swap(hp[a], hp[b]); swap(h[a], h[b]); } void down(int u) { int t=u; if(u*2<=cnt&&h[u*2]<h[t]) { t=u*2; } if(u*2+1<=cnt&&h[u*2+1]<h[t]) { t=u*2+1; } if(u!=t) { heap_swap(u, t); down(t); } } void up(int u) { while(u/2&&h[u]<h[u/2]) { heap_swap(u,u/2); u>>= 1; } } int main() { int n, m = 0; cin>>n; while (n--) { char op[5]; int k, x; cin>>op; if (!strcmp(op, "I")) { cin>>x; cnt++ ; m++; ph[m]=cnt; hp[cnt]= m; h[cnt]=x; up(cnt); } else if(!strcmp(op,"PM")) { cout<<h[1]<<endl; } else if(!strcmp(op,"DM")) { heap_swap(1,cnt); cnt-- ; down(1); } else if(!strcmp(op,"D")) { cin>>k; k=ph[k]; heap_swap(k,cnt); cnt-- ; up(k); down(k); } else { cin>>k>>x; k=ph[k]; h[k]=x; up(k); down(k); } } system("pause"); return 0; }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。