45分手写堆+数组链表求大佬帮调
查看原帖
45分手写堆+数组链表求大佬帮调
242039
goodier楼主2022/6/2 15:59
#include <bits/stdc++.h>
#define ll unsigned long long
using namespace std;
ll n,q,sum,k,ans,c[100010],d[100010];
struct node{
	ll val,it;
}Heap[400010];
struct Node{
	ll pre,nxt,d,it;
}L[400010];
void up(ll p)
{
	while(p)
	{
		if(Heap[p / 2].val > Heap[p].val)
		{
			L[Heap[p].it].it = p / 2,L[Heap[p / 2].it].it = p;
			swap(Heap[p],Heap[p / 2]);
			p /= 2;
		}
		else break;
	}
}
void down(ll p)
{
	ll son = p * 2;
	while(son <= sum)
	{
		if(son < sum && Heap[son].val > Heap[son + 1].val) son++;
		if(Heap[p].val > Heap[son].val)
		{
			L[Heap[p].it].it = son,L[Heap[son].it].it = p;
			swap(Heap[p],Heap[son]);
			p = son,son *= 2;	
		}
		else break;
	}
}
ll Ins(ll x,ll it)
{
	Heap[++sum].val = x,Heap[sum].it = it;

	return sum;
}
void Del(ll p)
{
	if(L[p].pre) L[L[p].pre].nxt = L[p].nxt;
	if(L[p].nxt) L[L[p].nxt].pre = L[p].pre;
}
void Rem(ll p)
{
	Del(Heap[p].it);
	L[Heap[sum].it].it = p;
	Heap[p] = Heap[sum--];
	up(p),down(p);
 } 
int main()
{
	scanf("%lld%lld",&n,&k);
	for(ll i = 1; i <= n; i++)
	{
		scanf("%lld",&c[i]);
		if(i > 1) d[i - 1] = c[i] - c[i - 1];
	}
	for(ll i = 1; i < n; i++)
	{
		++q;
		if(i > 1)L[q].pre = q - 1;
		if(i < n - 1)L[q].nxt = q + 1;
		L[q].d = d[i];
		L[q].it = Ins(d[i],q);
		up(sum);
	}
	for(ll i = 1; i <= k; i++)
	{
		ans += Heap[1].val;
		ll it = Heap[1].it;
		ll a = L[it].pre,b = L[it].nxt;
		Rem(1);
		if(a) Rem(L[a].it);
		if(b) Rem(L[b].it);
		L[q].it = Ins(L[a].d + L[b].d - L[it].d,++q);
		up(sum);
		L[q].d = L[a].d + L[b].d - L[it].d;
		L[q].pre = L[a].pre,L[L[a].pre].nxt = q;
		L[q].nxt = L[b].nxt,L[L[b].nxt].pre = q;
	}
	printf("%lld",ans);
	return 0;
}
2022/6/2 15:59
加载中...