题解:P11671 [USACO25JAN] Farmer John's Favorite Operation S
题解
简单分析一下题目,发现
将所有数随意转化为同一个数(下称转化数,即
先讨论元素个数为奇数情况。设选定的转化数左边有
若向左移动一个数,则
对于元素个数为偶数情况,因为转化数放在任意两元素间,两元素创造的贡献和恒定,即两元素距离。所以可以将中间两元素看做一个点,转化为奇数情况。在具体处理时,直接选取两元素的任意一个作为转化数即可。
然而本题稍微特殊一些,因为在模
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int a[200010],b[400010],pre[400010];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i]%m;
int ans=1e18;
sort(b+1,b+n+1);
for(int i=1;i<=n;i++) b[i+n]=b[i]+m;//断环成链处理
for(int i=1;i<=2*n;i++) pre[i]=pre[i-1]+b[i];//前缀和优化
for(int i=1;i<=n;i++){
int pos=(n/2)+(n%2==1)+i-1;//找中位数位置,分类讨论奇偶
int qian=(pos-i)*b[pos]-(pre[pos-1]-pre[i-1]);
int hou=(pre[i+n-1]-pre[pos])-(i+n-pos-1)*b[pos];
ans=min(ans,qian+hou);
}
cout<<ans<<endl;
}
return 0;
}