#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct State {
long long used, c;
long long S() const { return used - c; }
};
void solve() {
long long n, m, k;
cin >> n >> m >> k;
vector<long long> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<State> frontier;
frontier.reserve(8005);
frontier.push_back({0, 0});
// Static vector để tái sử dụng bộ nhớ cho mọi testcase (chống TLE do allocation)
static vector<State> list1, list2, next_states;
for (int i = 0; i < n; i++) {
long long req = (m - a[i]) % m;
bool can_reach_zero = false;
for (const auto& st : frontier) {
if (req <= st.c + k - st.used) {
can_reach_zero = true;
break;
}
}
if (can_reach_zero) {
list1.clear();
list2.clear();
for (const auto& st : frontier) {
long long c = st.c;
long long used = st.used;
// Phân nhánh 1: x1 <= c
if (c >= req) {
long long x1 = req + ((c - req) / m) * m;
if (list1.empty() || list1.back().c != x1) {
list1.push_back({used, x1});
}
}
// Phân nhánh 2: x2 >= c
long long x2 = (c <= req) ? req : req + ((c - req + m - 1) / m) * m;
long long u2 = used + x2 - c;
if (u2 <= k) {
if (!list2.empty() && list2.back().c == x2) {
if (u2 < list2.back().used) list2.back().used = u2;
} else {
list2.push_back({u2, x2});
}
}
}
// Gộp 2 list đã tự động sắp xếp bằng Two Pointers (O(F))
next_states.clear();
int p1 = 0, p2 = 0;
int sz1 = list1.size(), sz2 = list2.size();
while (p1 < sz1 || p2 < sz2) {
if (p1 < sz1 && p2 < sz2) {
if (list1[p1].c < list2[p2].c) next_states.push_back(list1[p1++]);
else if (list1[p1].c > list2[p2].c) next_states.push_back(list2[p2++]);
else {
next_states.push_back({min(list1[p1].used, list2[p2].used), list1[p1].c});
p1++; p2++;
}
} else if (p1 < sz1) {
next_states.push_back(list1[p1++]);
} else {
next_states.push_back(list2[p2++]);
}
}
// Lọc Pareto ngặt (O(F))
frontier.clear();
for (const auto& st : next_states) {
while (!frontier.empty() && frontier.back().used >= st.used) {
frontier.pop_back();
}
if (!frontier.empty() && frontier.back().S() <= st.S()) {
continue;
}
frontier.push_back(st);
}
// Cắt tỉa thông minh (Giữ mảng đầu cuối) để khóa Memory/Time bounds
if (frontier.size() > 8000) {
vector<State> reduced;
reduced.reserve(8000);
for (int j = 0; j < 4000; j++) reduced.push_back(frontier[j]);
for (int j = 0; j < 4000; j++) reduced.push_back(frontier[frontier.size() - 4000 + j]);
frontier = move(reduced);
}
a[i] = 0;
} else {
// Nếu không đạt 0, state tối ưu nhất bắt buộc là giá trị cũ của A[i]
// với lượng chi phí rẻ nhất (used cực tiểu).
long long min_used = frontier[0].used;
frontier.clear();
frontier.push_back({min_used, 0});
}
}
for (int i = 0; i < n; i++) {
cout << a[i] << (i == n - 1 ? "" : " ");
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
if (cin >> t) {
while (t--) {
solve();
}
}
return 0;
}