1. 程式人生 > >LOJ#2132. 「NOI2015」荷馬史詩

LOJ#2132. 「NOI2015」荷馬史詩

amp bitset 感覺 nbsp 個數 none sin splay cstring

$n \leq 100000$個數字,放進$k$叉樹裏,一個點只能放一個數,使所有數字乘以各自深度這個值之和最小的同時,最大深度的數字最小。

哈夫曼。這是我剛學OI那段時間看到的,感覺就是個很無聊的貪心,而且密碼學我也不學深對哈夫曼的應用也了解不多,沒想到出現在noi。

原來的哈夫曼只需要每次拿k個最小的數出來,建一個他們共同的父親並在一起,當作一個權值為他們權值之和的新點,用堆可以實現;由於$(n-1) \mod (k-1)$不一定為0,需要補幾個0點進去。相對於原來的哈夫曼,這裏多了個深度限制,那只需要把堆裏元素再記一下最大深度就可以了。

技術分享圖片
 1 //#include<iostream>
 2
#include<cstring> 3 #include<cstdio> 4 //#include<math.h> 5 //#include<set> 6 #include<queue> 7 //#include<bitset> 8 //#include<vector> 9 #include<algorithm> 10 #include<stdlib.h> 11 using namespace std; 12 13 #define LL long long 14 int qread()
15 { 16 char c; int s=0,f=1; while ((c=getchar())<0 || c>9) (c==-) && (f=-1); 17 do s=s*10+c-0; while ((c=getchar())>=0 && c<=9); return s*f; 18 } 19 20 //Pay attention to ‘-‘ , LL and double of qread!!!! 21 22 int n,K; 23 #define maxn 200011 24 struct qnode 25
{ 26 LL v; int dep; 27 bool operator > (const qnode &b) const {return v>b.v || (v==b.v && dep>b.dep);} 28 }; 29 priority_queue<qnode,vector<qnode>,greater<qnode> > q; 30 31 int main() 32 { 33 n=qread(); K=qread(); LL v; 34 for (int i=1;i<=n;i++) {scanf("%lld",&v); q.push((qnode){v,0});} 35 if ((n-1)%(K-1)) for (int i=1,to=(K-1)-(n-1)%(K-1);i<=to;i++) q.push((qnode){0,0}),n++; 36 LL ans=0; 37 for (int i=1,to=(n-1)/(K-1);i<=to;i++) 38 { 39 LL nv=0; int nd=0; 40 for (int j=1;j<=K;j++) nv+=q.top().v,nd=max(nd,q.top().dep),q.pop(); 41 ans+=nv; q.push((qnode){nv,nd+1}); 42 } 43 printf("%lld\n%d\n",ans,q.top().dep); 44 return 0; 45 }
View Code

LOJ#2132. 「NOI2015」荷馬史詩