1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| #include<bits/stdc++.h> #define LL long long #define PII pair<int, int> using namespace std; template <class T> inline void read(T &res) { res = 0; bool flag = 0; char c = getchar(); while('0' > c || c > '9') { if(c == '-') flag = 1; c = getchar();} while('0' <= c && c <= '9') res = (res << 3) + (res << 1) + (c ^ 48), c = getchar(); if(flag) res = -res; } template <class T, class ...Arg> inline void read(T &res, Arg &...com){ read(res), read(com...);} template <class T> void out(T res) { if(res > 9) out(res / 10); putchar(res % 10 + '0'); } template <class T> inline void write(T res) { if(res < 0) putchar('-'), res = -res; out(res), putchar('\n'); } const int N = 500 + 5, M = 5000000 + 5; int n, T, m, k; int d[N]; priority_queue<PII>q; inline void solve() { for(int i = 1;i <= n;i ++) q.push({d[i], i}); while(m != n - 1) { PII o = q.top(); q.pop(); o.first -= k; printf("%d %d\n", o.second, k); q.push(o); m --; } while(!q.empty()) d[q.top().second] = q.top().first, q.pop(); while(m --) { int minn = 1e9 + 7, id_minn, maxn = 0, id_maxn; for(int i = 1;i <= n;i ++) if(d[i] != 0) { if(minn >= d[i]) id_minn = i, minn = d[i]; if(maxn <= d[i]) id_maxn = i, maxn = d[i]; } printf("%d %d %d %d\n", id_minn, minn, id_maxn, k - minn); d[id_maxn] -= k - minn, d[id_minn] = 0; } } bitset<M>s[505]; int vis[N]; PII st[N]; int hh; inline void pout() { int cnt = hh - 1; while(cnt --) { PII minn = {1e9 + 7, 0}, maxn = {0, 0}; int id_maxn, id_minn; for(int i = 1;i <= hh;i ++) if(st[i].first != 0) { if(minn >= st[i]) id_minn = i, minn = st[i]; if(maxn <= st[i]) id_maxn = i, maxn = st[i]; } printf("%d %d %d %d\n", minn.second, minn.first, maxn.second, k - minn.first); st[id_minn].first -= minn.first, st[id_maxn].first -= k - minn.first; } } inline void split() { int sum = n * k; if(n == 3) return puts("-1"), void(); for(int i = 0;i <= n;i ++) s[i].reset(), vis[i] = 0; for(int i = 1;i <= n;i ++) d[i] -= k; s[0][sum] = 1; for(int i = 1;i <= n;i ++) { if(d[i] > 0) s[i] = s[i - 1] | (s[i - 1] << d[i]); else s[i] = s[i - 1] | (s[i - 1] >> (-d[i])); } if(!s[n][sum - k]) return puts("-1"), void(); int last = sum - k; hh = 0; for(int i = n;i >= 1;i --) if(s[i - 1][last - d[i]]) last -= d[i], vis[i] = 1; for(int i = 1;i <= n;i ++) if(vis[i]) st[++ hh] = {d[i] + k, i}; pout(); hh = 0; for(int i = 1;i <= n;i ++) if(!vis[i]) st[++ hh] = {d[i] + k, i}; pout(); } inline void work() { read(n, m, k); for(int i = 1;i <= n;i ++) read(d[i]); if(m >= n - 1) return solve(); return split(); } int main() { read(T); while(T --) work(); return 0; }
|