我的思路就是模2k之后用树状数组维护一下每个 ai 所点亮的区间。
wrong answer 2003rd numbers differ - expected: '877248279', found: '877248280'
感觉没道理会出这个错啊
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int MAXN = 200007;
template <typename T>
class TreeArray {
private:
vector<T> a, b;
int lowbit(int x) { return x & -x; }
void update(int pos, T val) {
for (int i = pos; i < a.size(); i += lowbit(i)) {
a[i] += val;
b[i] += pos * val;
}
}
public:
TreeArray(int n) : a(n + 1), b(n + 1) {}
void updateRange(int l, int r, T val) {
update(l, val);
update(r + 1, -val);
}
T prefixSum(int pos) {
T as = 0, bs = 0;
for (int i = pos; i > 0; i -= lowbit(i)) {
as += a[i];
bs += b[i];
}
return (pos + 1) * as - bs;
}
T rangeSum(int l, int r) { return prefixSum(r) - prefixSum(l - 1); }
void buildTree(vector<T>& arr) {
for (int i = 1; i < arr.size(); i++) {
update(i, arr[i] - arr[i - 1]);
}
}
};
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n, k;
cin >> n >> k;
TreeArray<ll> t(2 * k + 1);
vector<int> a(n + 1), c(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
c[i] = a[i] % (2 * k) + 1;
if (c[i] + k - 1 <= 2 * k) {
t.updateRange(c[i], c[i] + k - 1, 1);
} else {
t.updateRange(c[i], 2 * k, 1);
t.updateRange(1, c[i] - k - 1, 1);
}
}
ll base = *max_element(a.begin() + 1, a.end());
ll ans = -1;
for (int i = 1; i <= 2 * k; i++) {
if (t.rangeSum(i, i) == n) {
ll rel = base % (2 * k) + 1;
if (rel <= i) {
ans = i - rel + base;
} else {
ans = 2 * k - rel + i + base;
}
break;
}
}
cout << ans << "\n";
}
return 0;
}