// 嘘解法詰め合わせ // 嘘を組み合わせて一番良い解をとっても落ちることを確認する #include #include #include #include using namespace std; using lint = long long; lint ac_solution(const vector &A) { const int N = A.size(); priority_queue pq; lint last = 0; for (int i = 0; i < N; ++i) { pq.push(A[i]); if (i % 2 == 0) { last += pq.top(); pq.pop(); } } return last; } lint uso_pairwise(const vector &A) { const int N = A.size(); lint ret = A[0]; for (int i = 1; i + 1 < N; i += 2) ret += max(A[i], A[i + 1]); return ret; } lint uso2(const vector &A) { const int N = A.size(), K = (N + 1) / 2; vector cumsum(N + 1); for (int i = 0; i < N; ++i) cumsum[i + 1] = cumsum[i] + A[i]; lint last = cumsum[K]; lint ksum = 0; for (int k = 1; k <= K; ++k) { ksum += A[(K - k) * 2]; last = max(last, ksum + cumsum[K - k]); } return last; } // 「第 1 項までから 1 個選ぶ」「第 3 項までから 2 個選ぶ」... をやって総和を最大化する // 問題について様々な嘘解法をやって最も良いものを出力する lint uso_heuristics(const vector &A) { lint ret = 0; ret = max(ret, uso_pairwise(A)); ret = max(ret, uso2(A)); // ret = max(ret, ac_solution(A)); return ret; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int T; cin >> T; while (T--) { int N; cin >> N; vector A(N); for (auto &x : A) cin >> x; sort(A.begin(), A.end()); lint all = A.back(); for (int i = N - 1; i; --i) A[i] -= A[i - 1]; lint last = uso_heuristics(A); cout << ((N & 1) ? last : all - last) << '\n'; } }