题解:P14562 宇宙
P14562 宇宙
题目传送门
思路
被 TLE 创死了。
对
- 将
v_j 转换为u_j = v_j - 1 ,并对u_j 升序排序。 - 对于前缀和数组
S ,其中S[m] = \sum_{j=1}^m u_j 。 - 对每个
k ,用双指针维护最优的m ,使得\frac{S[m]}{m-k} 最小(对应最大的x ),最终x = \lfloor \frac{S[m]}{m-k} \rfloor 即可。
时间复杂度为
#include<bits/stdc++.h>
using namespace std;
#define int __int128
constexpr int N = 78787878;
int arr1[N], arr2[N], arr3[N], ans[N], n, m, sum = 2;
void write(int x){
if(x == 0) return;
if(x < 0){
putchar('-');
x = -x;
}
if(x / 10) write(x / 10);
putchar(x % 10 + '0');
}
int read(){
int x = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){
x = x * 10 + (ch - '0');
ch = getchar();
}
return x;
}
signed main(){
n = read(), m = read();
int nn = m, mm = n;
for(int i = 0; i < nn; i++){
int x;
x = read();
arr1[i] = x;
arr2[i] = arr1[i] - 1;
}
sort(arr2, arr2 + nn);
arr3[0] = 0;
for(int i = 1; i <= nn; i++) arr3[i] = arr3[i - 1] + arr2[i - 1];
for(int k = 1; k <= nn - 1; k++){
sum = max(sum, (k + 1));
while(sum < nn){
int t1 = sum - k;
int t2 = (sum + 1) - k;
int a = arr3[sum] * t2;
int b = arr3[sum + 1] * t1;
if(a > b){
sum++;
}else{
break;
}
}
int t = sum - k;
ans[k - 1] = arr3[sum] / t;
}
for(int i = 0; i < nn - 1; i++){
if(ans[i] == 0) putchar('0');
else write(ans[i]);
if(i != nn - 2) putchar(' ');
else putchar('\n');
}
return 0;
}
:::