#include<iostream> #include<cmath> #define rep(i,a,b) for(int i = (a); i <= (b); i ++ ) usingnamespace std; constint N = 200010; int n; int h[N], a[N], rk[N];
#include<iostream> #include<algorithm> #include<vector> #define int long long #define rep(i, a, b) for(int i = (a); i <= (b); i ++ ) usingnamespace std; constint N = 200010;
voidsolve() { int n, m; cin >> n >> m; vector<int> a(2 * n + 10); rep(i, 1, n) cin >> a[i], a[i] %= m; // 由于a和x同余m, 所以可以先都 % m sort(a.begin() + 1, a.begin() + n + 1); // 破环成链 // 这里至于为什么加m, 其实比较模糊 // 可以理解为是为了保证a升序, 之后的前缀和计算可以正确进行 // 我的感觉就是由于所有a都是在0到m-1之间循环, 虽然不确定在正确答案中是向上加还是向下减, // 但是还是一定只有两个方向, 这样复制数组再整体加m的做法其实就是促成一个加一个减. rep(i, n + 1, 2 * n) a[i] = a[i - n] + m; // 记录前缀和 vector<int> pre(2 * n + 10); rep(i, 1, 2 * n) pre[i] = a[i] + pre[i - 1]; int ans = 1E18; // 枚举环上每个点 rep(i, 1, n) { int l = i, r = i + n - 1; int mid = (l + r + 1) / 2; int res; if (n % 2 == 0) { // 偶数的时候,[mid, r] - [l, mid - 1]; res = pre[r] - 2 * pre[mid - 1] + pre[l - 1]; } else { // 奇数的时候,[mid + 1, r] - [l, mid - 1]; res = pre[r] - pre[mid] - pre[mid - 1] + pre[l - 1]; } ans = std::min(ans, res); } cout << ans << endl; }