一、堆排序
838. 堆排序
输入一个长度为 nn 的整数数列,从小到大输出前 mm 小的数。
输入格式
第一行包含整数 nn 和 mm。
第二行包含 nn 个整数,表示整数数列。
输出格式
共一行,包含 mm 个整数,表示整数数列中前 mm 小的数。
数据范围
1≤m≤n≤1051≤m≤n≤105,
1≤数列中元素≤1091≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
思路:主要是down函数,将插入的数三角比较,和最大的那个交换,再向下维护交换之后的三角形
#include<iostream>
using namespace std;
#include<vector>
#include<bits/stdc++.h>
#define N 1000010
int p[N];
int n,m,sizeop;
void down(int x)
{
int t=x;
if(2*x<=sizeop&&p[t]>p[2*x])t=2*x;
if(2*x+1<=sizeop&&p[t]>p[2*x+1])t=2*x+1;
if(t!=x)
{
swap(p[t],p[x]);
down(t);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i]);
}
sizeop=n;
for(int i=n/2;i;i--)
{
down(i);
}
while(m--)
{
cout<<p[1]<<" ";
p[1]=p[sizeop--];
down(1);
}
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------
二、
839. 模拟堆
维护一个集合,初始时集合为空,支持如下几种操作:
I x
,插入一个数 xx;PM
,输出当前集合中的最小值;DM
,删除当前集合中的最小值(数据保证此时的最小值唯一);D k
,删除第 kk 个插入的数;C k x
,修改第 kk 个插入的数,将其变为 xx;
现在要进行 NN 次操作,对于所有第 22 个操作,输出当前集合的最小值。
输入格式
第一行包含整数 NN。
接下来 NN 行,每行包含一个操作指令,操作指令为 I x
,PM
,DM
,D k
或 C k x
中的一种。
输出格式
对于每个输出指令 PM
,输出一个结果,表示当前集合中的最小值。
每个结果占一行。
数据范围
1≤N≤1051≤N≤105
−109≤x≤109−109≤x≤109
数据保证合法。
输入样例:
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM
输出样例:
-10
6
思路:明天补充
#include<iostream>
using namespace std;
#include<vector>
#include<bits/stdc++.h>
#define N 1000010
int p[N],hp[N],ph[N];
int n,sizeop;
void hswap(int u,int v)
{
swap(p[u],p[v]);
swap(hp[u],hp[v]);
swap(ph[hp[u]],ph[hp[v]]);
}
void down(int u)
{
int t=u;
if(u*2<=sizeop&&p[t]>p[u*2]) t=u*2;
if(u*2+1<=sizeop&&p[t]>p[u*2+1]) t=u*2+1;
if(u!=t)
{
hswap(u,t);
down(t);
}
}
void up(int u)
{
if(u/2>0&&p[u]<p[u/2])
{
hswap(u,u/2);
up(u>>1);
}
}
int main()
{
scanf("%d",&n);
int m=0;//记录插入数个数
while(n--)
{
string str;
cin>>str;
if(str=="I")
{
int a;
scanf("%d",&a);
m++;
p[++sizeop]=a;
ph[m]=sizeop;
hp[sizeop]=m;
up(sizeop);
}
else if(str=="PM")
{
cout<<p[1]<<endl;
}
else if(str=="DM")
{
hswap(1,sizeop--);
down(1);
}
else if(str=="D")
{
int a;
scanf("%d",&a);
int u=ph[a];
hswap(u,sizeop);
sizeop--;
down(u);
up(u);
}
else
{
int k,x;
scanf("%d%d",&k,&x);
p[ph[k]]=x;
down(ph[k]);
up(ph[k]);
}
}
return 0;
}