1. 程式人生 > 實用技巧 >#佇列#洛谷 6033 合併果子 加強版

#佇列#洛谷 6033 合併果子 加強版

題目


分析

首先必須做到\(O(n)\)的時間複雜度,
第一次排序考慮使用桶排,由於合併後的果子也是升序的,
考慮用兩個佇列分別裝下原果子和合並後的果子,用兩個指標判斷一下即可


程式碼

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=100011,M=20000011; typedef long long lll;
int CNT[N],mn[2],n; long long a[M],ans;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	for (n=iut();n;--n) ++CNT[iut()];
	for (rr int i=1;i<N;++i)
	for (rr int j=1;j<=CNT[i];++j)
	    a[++n]=i;
	rr int l=1,r=n+1,head=n;
	for (rr int i=1;i<n;++i){
		for (rr int j=0;j<2;++j){
			if ((a[l]<=a[r]&&l<=n)||!a[r]) mn[j]=l++;
			    else if (r<=head) mn[j]=r++; else mn[j]=l++;
		}
		ans+=a[++head]=a[mn[0]]+a[mn[1]];
	}
	return !printf("%lld",ans);
}