Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #pragma GCC target ("avx2")
- #pragma GCC optimization ("O3")
- #pragma GCC optimization ("unroll-loops")
- #define ll long long
- #define MOD 1000000007;
- #define got cout<<"Yes\n"; return;
- #define got0 cout<<"Yes\n"; return 0;
- #define bhak cout<<"No\n"; return;
- #define bhak0 cout<<"No\n"; return 0;
- #define bas cout<<"\n";
- struct Dsu{
- vector<int> a, bulk;
- int comp;
- Dsu(int n){
- a.resize(n + 1);
- bulk.assign(n + 1, 1);
- for(int i = 0; i <= n; i++) {
- a[i] = i;
- }
- comp = n;
- };
- int root(int i) {
- while(a[i] != i) {
- i = a[i];
- a[i] = a[a[i]];
- }
- return i;
- }
- void merge(int x, int y) {
- int rx = root(x), ry = root(y);
- if(rx == ry)
- return;
- comp--;
- if(bulk[rx] < bulk[ry]) {
- swap(rx, ry);
- }
- bulk[rx] += bulk[ry];
- a[ry] = a[rx];
- }
- };
- // Segment Tree functions
- ll constructSegmentTree(ll ss, ll se, ll si, vector<int> &arr, vector<int> &segTree);
- ll getRangeSumRec(ll ss, ll se, ll qs, ll qe, ll si, vector<int> &segTree);
- void updateItem(ll ss, ll se, ll i, ll si, ll diff, vector<int> &segTree);
- // Initially segTree has size - "4n", ss=0, se=n-1, i=0
- ll constructSegmentTree(ll ss, ll se, ll si, vector<int> &arr, vector<int> &segTree){
- if(ss==se){
- segTree[si] = arr[ss];
- return arr[si];
- }
- ll mid = ss + (se-ss)/2;
- return segTree[si] = constructSegmentTree(ss, mid, 2*si+1, arr, segTree)
- + // Required Operation
- constructSegmentTree(mid+1, se, 2*si+2, arr, segTree);
- }
- // Initially ss=0, se =n-1, qs, qe - user range input, i=0
- ll getRangeSumRec(ll ss, ll se, ll qs, ll qe, ll si, vector<int> &segTree){
- if(se<qs || ss>qe){
- return 0;
- }
- if(qs<=ss && qe>=se){
- return segTree[si];
- }
- ll mid = ss + (se-ss)/2;
- return getRangeSumRec(ss, mid, qs, qe, 2*si+1, segTree)
- + // Required Operation
- getRangeSumRec(mid+1, se, qs, qe, 2*si+2, segTree);
- }
- // Updating the value at index 'i' with +=diff
- void updateItem(ll ss, ll se, ll i, ll si, ll diff, vector<int> &segTree){
- if(i<ss || i>se){
- return;
- }
- segTree[si] += diff; // Required Operation
- if(ss==se){
- return;
- }
- ll mid = ss+ (se-ss)/2;
- updateItem(ss, mid, i, 2*si+1, diff, segTree);
- updateItem(mid+1, se, i, 2*si+2, diff, segTree);
- }
- void solve();
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- cout.tie(NULL);
- ll t;
- t=1;
- cin>>t;
- while(t--){
- solve();
- }
- return 0;
- }
- void solve(){
- ll n, m; cin>>n>>m;
- vector<vector<ll>> vec(n, vector<ll> (m));
- ll sum = 0;
- for(ll i=0; i<n; ++i){
- for(ll j=0; j<m; ++j){
- cin>>vec[i][j];
- sum += vec[i][j];
- }
- }
- if(sum%n!=0){
- cout<<-1; bas
- return;
- }
- map<ll,ll> mp;
- for(ll i=0; i<n; ++i){
- mp[i] = accumulate(vec[i].begin(), vec[i].end(), 0) - sum/n;
- // cout<<mp[i]<<" ";
- }
- vector<vector<ll>> extra(m), kami(m);
- for(ll j=0; j<m; ++j){
- for(ll i=0; i<n; ++i){
- if(mp[i]>0){
- // extra wala
- if(vec[i][j]==1){
- extra[j].push_back(i);
- }
- }
- else if(mp[i]<0) {
- // kami wala
- if(vec[i][j]==0){
- kami[j].push_back(i);
- }
- }
- }
- }
- // for(ll i=0; i<m; ++i){
- // cout<<i<<":: ";
- // for(auto a : extra[i]){
- // cout<<a<<" ";
- // }
- // bas
- // }
- map<ll,ll> extraMp, kamiMp;
- map<pair<ll,ll>, ll> vis;
- vector<vector<ll>> ans;
- for(ll i=0; i<n; ++i){
- for(ll j=0; j<m; ++j){
- // already fucked up
- if(mp[i]==0) break;
- // extra wala
- if(mp[i]>0){
- if(vec[i][j]==0) continue;
- ll taken = kamiMp[j];
- vector<ll> poss = kami[j];
- if(taken>=poss.size()) continue;
- ll swapper = poss[taken];
- if(vis[{i,j}]==1 || vis[{swapper, j}]==1) continue;
- // cout<<swapper+1<<" "<<i+1<<" "<<j+1; bas
- ans.push_back({swapper+1, i+1, j+1});
- mp[i]--;
- mp[swapper]++;
- kamiMp[j]++;
- swap(vec[i][j], vec[swapper][j]);
- vis[{i,j}]=1;
- vis[{swapper, j}]=1;
- }
- // kami wala
- else if(mp[i]<0){
- if(vec[i][j]==1) continue;
- ll taken = extraMp[j];
- vector<ll> poss = extra[j];
- if(taken>=poss.size()) continue;
- ll swapper = poss[taken];
- if(vis[{i,j}]==1 || vis[{swapper, j}]==1) continue;
- // cout<<swapper+1<<" "<<i+1<<" "<<j+1; bas
- ans.push_back({swapper+1, i+1, j+1});
- mp[i]++;
- mp[swapper]--;
- extraMp[j]++;
- swap(vec[i][j], vec[swapper][j]);
- vis[{i,j}]=1;
- vis[{swapper, j}]=1;
- }
- }
- }
- for(ll i=0; i<n; ++i){
- if(mp[i]!=0){
- cout<<-1; bas
- return;
- }
- }
- cout<<ans.size(); bas
- for(auto pr : ans){
- for(auto a : pr){
- cout<<a<<" ";
- }
- bas
- }
- }
Add Comment
Please, Sign In to add comment