# 【思路】

$\underset{n\to +\mathrm{\infty }}{lim}\sum _{i=1}^{n}\frac{1}{i}=\mathrm{ln}n+\gamma$

$\underset{n\to +\mathrm{\infty }}{lim}\sum _{i=1}^{n}\frac{n}{i}=n\mathrm{ln}n+\gamma \cdot n=O\left(n\mathrm{log}n\right)$

# 【代码】

#include <queue>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 200000 + 10, inf = 0x7f7f7f7f;
bool icmp(int a,int b){return a < b;}

class array_item{
int a[maxn], pre[maxn], n;
inline int getint(){
int ans=0;bool flag=0;char c=getchar();
while(!isdigit(c)){flag|=c=='-';c=getchar();}
while( isdigit(c)){ans=ans*10+c-'0';c=getchar();}
return flag?-ans:ans;
}
public:
inline int operator[](int idx){
if(idx > n || idx <= 0) return inf;
return a[idx];
}
inline int sum(int L,int R){
return pre[R] - pre[L-1];
}
inline void input(const int n){
this->n = n;
pre[0]=0;
for(int i=1; i<=n; i++) a[i]   = getint();
sort(a+1, a+n+1, icmp);
for(int i=1; i<=n; i++) pre[i] = pre[i-1] + a[i];
}
}array;

class minor{
queue<int>Q;
inline int size(){return n - ahead + 1 + Q.size();}
inline int run(){
int lst = ahead + k - 1;
int sum = 0;
while(!Q.empty() && array[lst] > Q.front()){
sum += Q.front(); Q.pop(); lst--;
}
Q.push(sum); ans += sum;
return sum;
}
public:
void init(const int k,const int n){
this->k = k; this->n = n;
int zcnt =((k-1) - n%(k-1) + 1)%(k-1); //put zero
int first = k - zcnt; ahead = first + 1;
if(first){
ans = array.sum(1,first);
Q.push(ans);
}else ans = 0;
}
int solve(){
while(size()>1) run();
while(!Q.empty()) Q.pop();
return ans;
}
}launcher;

int main(){
freopen("stone.in", "r",stdin);
freopen("stone.out","w",stdout);
int n; scanf("%d", &n);
array.input(n);
for(int i=2; i<=n; i++){
launcher.init(i,n);
int ans=launcher.solve();
printf("%d\n",ans);
}
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120