sandeep03edu

Untitled

Dec 17th, 2022
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.27 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #pragma GCC target ("avx2")
  5. #pragma GCC optimization ("O3")
  6. #pragma GCC optimization ("unroll-loops")
  7. #define ll  long long
  8. #define MOD 1000000007;
  9.  
  10. #define got cout<<"Yes\n"; return;
  11. #define got0 cout<<"Yes\n"; return 0;
  12.  
  13. #define bhak cout<<"No\n"; return;
  14. #define bhak0 cout<<"No\n"; return 0;
  15.  
  16. #define bas cout<<"\n";
  17.  
  18. struct Dsu{
  19.     vector<int> a, bulk;
  20.     int comp;
  21.     Dsu(int n){
  22.         a.resize(n + 1);
  23.         bulk.assign(n + 1, 1);
  24.         for(int i = 0; i <= n; i++) {
  25.             a[i] = i;
  26.         }
  27.         comp = n;
  28.     };
  29.    
  30.     int root(int i) {
  31.         while(a[i] != i) {
  32.             i = a[i];
  33.             a[i] = a[a[i]];
  34.         }
  35.         return i;
  36.     }
  37.    
  38.     void merge(int x, int y) {
  39.         int rx = root(x), ry = root(y);
  40.         if(rx == ry)  
  41.             return;
  42.         comp--;
  43.         if(bulk[rx] < bulk[ry]) {
  44.             swap(rx, ry);
  45.         }
  46.         bulk[rx] += bulk[ry];
  47.         a[ry] = a[rx];
  48.     }
  49. };
  50.  
  51. // Segment Tree functions
  52. ll constructSegmentTree(ll ss, ll se, ll si, vector<int> &arr, vector<int> &segTree);
  53. ll getRangeSumRec(ll ss, ll se, ll qs, ll qe, ll si, vector<int> &segTree);
  54. void updateItem(ll ss, ll se,  ll i, ll si, ll diff,  vector<int> &segTree);
  55.  
  56.  
  57. // Initially segTree has size - "4n", ss=0, se=n-1, i=0
  58. ll constructSegmentTree(ll ss, ll se, ll si, vector<int> &arr, vector<int> &segTree){
  59.     if(ss==se){
  60.         segTree[si] = arr[ss];
  61.         return arr[si];
  62.     }
  63.    
  64.     ll mid = ss + (se-ss)/2;
  65.    
  66.     return segTree[si] = constructSegmentTree(ss, mid, 2*si+1, arr, segTree)
  67.                             + // Required Operation
  68.                          constructSegmentTree(mid+1, se, 2*si+2, arr, segTree);
  69. }
  70.  
  71.  
  72. // Initially ss=0, se =n-1, qs, qe - user range input, i=0
  73. ll getRangeSumRec(ll ss, ll se, ll qs, ll qe, ll si, vector<int> &segTree){
  74.     if(se<qs || ss>qe){
  75.         return 0;
  76.     }
  77.    
  78.     if(qs<=ss && qe>=se){
  79.         return segTree[si];
  80.     }
  81.    
  82.     ll mid = ss + (se-ss)/2;
  83.    
  84.     return getRangeSumRec(ss, mid, qs, qe, 2*si+1, segTree)
  85.             + // Required Operation
  86.            getRangeSumRec(mid+1, se, qs, qe, 2*si+2, segTree);
  87. }
  88.  
  89. // Updating the value at index 'i' with +=diff
  90. void updateItem(ll ss, ll se,  ll i, ll si, ll diff,  vector<int> &segTree){
  91.     if(i<ss || i>se){
  92.         return;
  93.     }
  94.    
  95.     segTree[si] += diff; // Required Operation
  96.    
  97.     if(ss==se){
  98.         return;
  99.     }
  100.    
  101.     ll mid = ss+ (se-ss)/2;
  102.    
  103.     updateItem(ss, mid, i, 2*si+1, diff, segTree);
  104.     updateItem(mid+1, se, i, 2*si+2, diff, segTree);
  105. }
  106.  
  107. void solve();
  108.  
  109. int main() {
  110.     ios_base::sync_with_stdio(false);
  111.     cin.tie(NULL);
  112.     cout.tie(NULL);
  113.  
  114.     ll t;
  115.     t=1;
  116.     cin>>t;
  117.     while(t--){
  118.         solve();
  119.     }
  120.  
  121.     return 0;
  122. }
  123.  
  124. void solve(){
  125.     ll n, m; cin>>n>>m;
  126.    
  127.     vector<vector<ll>> vec(n, vector<ll> (m));
  128.     ll sum = 0;
  129.     for(ll i=0; i<n; ++i){
  130.         for(ll j=0; j<m; ++j){
  131.             cin>>vec[i][j];
  132.             sum += vec[i][j];
  133.         }
  134.     }
  135.    
  136.     if(sum%n!=0){
  137.         cout<<-1; bas
  138.         return;
  139.     }
  140.    
  141.     map<ll,ll> mp;
  142.    
  143.     for(ll i=0; i<n; ++i){
  144.         mp[i] = accumulate(vec[i].begin(), vec[i].end(), 0) - sum/n;
  145.         // cout<<mp[i]<<" ";
  146.     }
  147.    
  148.     vector<vector<ll>> extra(m), kami(m);
  149.    
  150.     for(ll j=0; j<m; ++j){
  151.         for(ll i=0; i<n; ++i){
  152.             if(mp[i]>0){
  153.                 // extra wala
  154.                 if(vec[i][j]==1){
  155.                     extra[j].push_back(i);
  156.                 }
  157.             }
  158.             else if(mp[i]<0) {
  159.                 // kami wala
  160.                 if(vec[i][j]==0){
  161.                     kami[j].push_back(i);
  162.                 }
  163.                
  164.             }
  165.         }
  166.     }
  167.    
  168.     // for(ll i=0; i<m; ++i){
  169.     //     cout<<i<<":: ";
  170.     //     for(auto a : extra[i]){
  171.     //         cout<<a<<" ";
  172.     //     }
  173.     //     bas
  174.     // }
  175.    
  176.     map<ll,ll> extraMp, kamiMp;
  177.    
  178.     map<pair<ll,ll>, ll> vis;
  179.    
  180.     vector<vector<ll>> ans;
  181.     for(ll i=0; i<n; ++i){
  182.         for(ll j=0; j<m; ++j){
  183.            
  184.             // already fucked up
  185.             if(mp[i]==0) break;
  186.            
  187.             // extra wala
  188.             if(mp[i]>0){
  189.                 if(vec[i][j]==0) continue;
  190.                
  191.                 ll taken = kamiMp[j];
  192.                 vector<ll> poss = kami[j];
  193.                
  194.                 if(taken>=poss.size()) continue;
  195.                
  196.                 ll swapper = poss[taken];
  197.                
  198.                 if(vis[{i,j}]==1 || vis[{swapper, j}]==1) continue;
  199.                
  200.                 // cout<<swapper+1<<" "<<i+1<<" "<<j+1; bas
  201.                 ans.push_back({swapper+1, i+1, j+1});
  202.                
  203.                 mp[i]--;
  204.                 mp[swapper]++;
  205.                 kamiMp[j]++;
  206.                
  207.                 swap(vec[i][j], vec[swapper][j]);
  208.                
  209.                 vis[{i,j}]=1;
  210.                 vis[{swapper, j}]=1;
  211.                
  212.                
  213.             }
  214.             // kami wala
  215.             else if(mp[i]<0){
  216.                 if(vec[i][j]==1) continue;
  217.                
  218.                 ll taken = extraMp[j];
  219.                 vector<ll> poss = extra[j];
  220.                
  221.                 if(taken>=poss.size()) continue;
  222.                
  223.                 ll swapper = poss[taken];
  224.                
  225.                 if(vis[{i,j}]==1 || vis[{swapper, j}]==1) continue;
  226.                
  227.                 // cout<<swapper+1<<" "<<i+1<<" "<<j+1; bas
  228.                 ans.push_back({swapper+1, i+1, j+1});
  229.                
  230.                 mp[i]++;
  231.                 mp[swapper]--;
  232.                 extraMp[j]++;
  233.                
  234.                 swap(vec[i][j], vec[swapper][j]);
  235.                
  236.                 vis[{i,j}]=1;
  237.                 vis[{swapper, j}]=1;
  238.            
  239.                
  240.                
  241.             }
  242.            
  243.            
  244.            
  245.         }
  246.     }
  247.    
  248.     for(ll i=0; i<n; ++i){
  249.         if(mp[i]!=0){
  250.             cout<<-1; bas
  251.             return;
  252.         }
  253.     }
  254.    
  255.    
  256.     cout<<ans.size(); bas
  257.    
  258.     for(auto pr : ans){
  259.         for(auto a : pr){
  260.             cout<<a<<" ";
  261.         }
  262.         bas
  263.     }
  264.    
  265.    
  266. }
Add Comment
Please, Sign In to add comment