分析:
题意本质就是找点在数组中任意一个位置时和所有的端点之间的距离和,但是直接暴力会超时,可以对数组排个序,设当前遍历的是xi,那么此时求的到各端点的距离就是j从1 ~ i - 1的所有端点与xi的距离之和,也就是所有xi - xj + 1的和(1<=j<=i-1),另一部分就是xi的右边所有xj - xi + 1的和。将式子化简,就有
也就得到一个公式,就可以优化时间。
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T --) {
int n;
cin >> n;
vector<pair<long long, int>> x(n);
long long sum = 0;
for(int i = 0; i < n; i ++) {
cin >> x[i].first;
x[i].second = i;
sum += x[i].first;
}
vector<long long> ans(n);
sort(x.begin(), x.end());
long long cnt = 0;
for(int i = 0; i < n; i ++) {
long long res = n + x[i].first * (2 * i - n) - cnt + sum;
cnt += x[i].first;
sum -= x[i].first;
ans[x[i].second] = res;
}
for(int i = 0; i < n; i ++) cout << ans[i] << ' ';
cout << '\n';
}
}