题意很简单:从左到右取点,输出该点到每个点的距离之和
思路:
1.对一个有序的序列进行计算,我们发现从左往右,左边点数的距离会增加,右边点数的距离会减小
2.因此我们只需暴力的计算第一个点到所有点的距离之和,接下来的点只需一步就可计算出来
2.1 ans+=左边的点数之和移动的距离,ans-=右边包括自己的点数之和移动的距离
注意:
1.计算会爆int所以记得开LL
2.移动距离不用+1,比如:1->3,增加的是3,在3->4的情况下1->4,距离为4,也就是3+1(4-3).
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
void solve() {
int n;
cin >> n;
vector<pair<int, int>> v(n+1);
for (int i = 1; i <= n; i++) {
cin >> v[i].first;
v[i].second = i;//记录下标
}
sort(v.begin(), v.end());
LL ans = 0;
vector<LL> res(n + 1);
for (int i = 1; i <= n; i++) ans += v[i].first - v[1].first + 1;
res[v[1].second] = ans;
for (int i = 2; i <= n; i++) {
ans += 1LL*(i - 1) * (v[i].first - v[i - 1].first );//注意会爆int,所以乘以1LL
ans -= 1LL*(n - i + 1) * (v[i].first - v[i-1].first );//不用+1
res[v[i].second] = ans;
}
for (int i = 1; i <= n; i++) cout << res[i] << ' ';
cout << '\n';
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}