1. 程式人生 > >洛谷 P3378 【模板】堆

洛谷 P3378 【模板】堆

什麽 als www har 操作 space return 有關 bit

題目地址:

$Luogu$:https://www.luogu.org/problemnew/show/P3378

那麽我們一看到題目應該就會寫這道題了吧。

我們需要支(資)持(辭)三個操作:

1、插入一個數入小根堆(小根隊(少先隊))

2、輸出小根堆的最小值。

3、刪除小根堆的最小值。

由於我們知道,小根堆的最小值就是它的根,所以這題就很簡單了。

你不用管什麽$N<=10^6$,那些都沒有關系。

第一個和第三個操作我們需要寫兩個函數來解決。第二個操作直接輸出即可。

第一個函數:插入函數。

void insert(int x)
{
    h[++l]=x;
    up(l);
}

第二個函數:刪除函數。

void _delete(int x)
{
    h[x]=h[l--];
    up(x);
    down(x);
}

另附上浮操作$up$以及下沈操作$down$所用的函數。

void up(int x)
{
    while(x>1&&h[x]<h[x>>1])
    {
        swap(h[x], h[x>>1]);
        x>>=1;
    }
}
void down(int x)
{
    int
y=x<<1; while(y<=l) { if(y+1<=l&&h[y+1]<h[y]) y++; if(h[y]<h[x]) { swap(h[x], h[y]); x=y, y=x<<1; } else break; } }

代碼如下:

$code$

#include<bits/stdc++.h>
using namespace std;
const int maxN=1000000+1;
int h[maxN], n, l;
void read(int &), insert(int), up(int), down(int), _delete(int);
int main()
{
	read(n);
	for(int i=1; i<=n; i++)
	{
		int x;
		read(x);
		if(x==1)
		{
			int y;
			read(y);
			insert(y); 
		}
		if(x==2) printf("%d\n", h[1]);
		if(x==3) _delete(1);
		
	}
	return 0;
}
void read(int &x)
{
	x=0;
	char c=getchar();
	while(c<‘0‘||c>‘9‘) c=getchar();
	while(c>=‘0‘&&c<=‘9‘)
	{
		x=x*10+c-‘0‘;
		c=getchar();
	}
}
void up(int x)
{
	while(x>1&&h[x]<h[x>>1])
	{
		swap(h[x], h[x>>1]);
		x>>=1;
	}
}
void down(int x)
{
	int y=x<<1;
	while(y<=l)
	{
		if(y+1<=l&&h[y+1]<h[y]) y++;
		if(h[y]<h[x])
		{
			swap(h[x], h[y]);
			x=y, y=x<<1;
		}
		else break;
	}
}
void insert(int x)
{
	h[++l]=x;
	up(l);
}
void _delete(int x)
{
	h[x]=h[l--];
	up(x);
	down(x);
}

  

洛谷 P3378 【模板】堆