CF1857E Power of Points
2023-08-08 22:59:22 CF1857E solution
思路
我们发现每个点的答案其实是它与之前的点的答案加上与后面的点的答案加上与自己的答案。而与前面和与后面的前后缀答案都是可以通过递推的方式得到的,我们令 \(pre_i\) 表示 \(i\) 点的前缀答案,\(sub_i\) 表示 \(i\) 点的后缀答案,\(x_i\) 表示 \(i\) 点的坐标,那么有:
\[pre_i=pre_{i-1}-(x_i-x_{i-1})\times(n-i+1)-1\\ sub_i=sub_{i+1}-(x_{i+1}-x_i)\times i-1
\]
代码有点丑,见谅。
\(Code\)
struct node{
ll v,id,ans1,ans2;
inline bool operator <(const node &w)const{
return v<w.v;
}
}a[200005];
ll ans[200005];
ll T,n;
int main(){
for(T=read();T--;){
n=read();
for(ll i=1;i<=n;i++){
a[i].v=read();
a[i].id=i;
a[i].ans1=a[i].ans2=0;
}
sort(a+1,a+1+n);
for(ll i=2;i<=n;i++){
a[1].ans1+=a[i].v-a[1].v+1;
}
for(ll i=1;i<n;i++){
a[n].ans2+=a[n].v-a[i].v+1;
}
for(ll i=2;i<n;i++){
a[i].ans1+=a[i-1].ans1-1ll*(a[i].v-a[i-1].v)*(n-i+1)-1;
}
for(ll i=n-1;i>=2;--i){
a[i].ans2+=a[i+1].ans2-1ll*(a[i+1].v-a[i].v)*i-1;
}
for(ll i=1;i<=n;i++)ans[a[i].id]=a[i].ans1+a[i].ans2;
for(ll i=1;i<=n;i++){
printf("%lld ",ans[i]+1);
}
puts("");
}
}