knightL

Yandex D

Oct 9th, 2021
1,852
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.54 KB | None | 0 0
  1. #include <iostream>
  2. #include <numeric>
  3. #include <algorithm>
  4. #include <set>
  5. #include <map>
  6. #include <queue>
  7. #include <cassert>
  8. #include <vector>
  9. #include <string>
  10. using namespace std;
  11.  
  12. typedef long long ll;
  13.  
  14. vector<vector<int> > horizontal_fold(vector<vector<int> > v)
  15. {
  16.     int h = v.size();
  17.     int w = v[0].size();
  18.  
  19.     vector<vector<int> > res(h/2, vector<int>(w));
  20.  
  21.     for(int i=0;i<h/2;i++)
  22.         for(int j=0;j<w;j++)
  23.             res[i][j] = v[i][j] + v[h-1-i][j];
  24.     return res;
  25. }
  26.  
  27. vector<vector<int> > vertical_fold(vector<vector<int> > v)
  28. {
  29.     int h = v.size();
  30.     int w = v[0].size();
  31.  
  32.     vector<vector<int> > res(h, vector<int>(w/2));
  33.  
  34.     for(int i=0;i<h;i++)
  35.         for(int j=0;j<w/2;j++)
  36.             res[i][j] = v[i][j] + v[i][w-1-j];
  37.     return res;
  38. }
  39.  
  40. void print_matrix(vector<vector<int> > v)
  41. {
  42.     int h = v.size();
  43.     int w = v[0].size();
  44.  
  45.     puts("=====================");
  46.     for(int i=0;i<h;i++)
  47.     {
  48.         for(int j=0;j<w;j++)
  49.         {
  50.             if(j) putchar(' ');
  51.             printf("%3d", v[i][j]);
  52.         }
  53.         puts("");
  54.     }
  55.     puts("=====================");
  56. }
  57.  
  58. struct Matrix
  59. {
  60.     int n,m;
  61.     ll a00;
  62.     ll dr, dc;
  63.  
  64.     Matrix(int n=0, int m=0, ll a00=0, ll dr=0, ll dc=0):
  65.         n(n),
  66.         m(m),
  67.         a00(a00),
  68.         dr(dr),
  69.         dc(dc)
  70.     {
  71.     }
  72.  
  73.     Matrix vertical_fold() const
  74.     {
  75.         return Matrix(
  76.                     n/2,
  77.                     m,
  78.                     a00 + (a00+dr*(n-1)),
  79.                     0,
  80.                     2*dc
  81.                 );
  82.     }
  83.  
  84.     Matrix horizontal_fold() const
  85.     {
  86.         return Matrix(
  87.                     n,
  88.                     m/2,
  89.                     a00 + (a00+dc*(m-1)),
  90.                     2*dr,
  91.                     0
  92.                 );
  93.     }
  94. };
  95.  
  96. struct Range
  97. {
  98.     ll l, r, step;
  99.     Range(ll l=0, ll r=0, ll step=0):
  100.         l(l),
  101.         r(r),
  102.         step(step)
  103.     {}
  104. };
  105.  
  106. ll solve(int n, int m)
  107. {
  108.     Matrix mtr = Matrix(n, m, 1, m, 1);
  109.     vector<Range> ranges;
  110.     ranges.push_back( Range(1, n*m, 1) );
  111.     ll res = n*m;
  112.  
  113. //  assert(n*m<=(1<<16));
  114. //  set<int> used;
  115. //  for(int i=0;i<n;i++)
  116. //      for(int j=0;j<m;j++)
  117. //          used.insert(mtr.a00 + i * mtr.dr + j * mtr.dc);
  118. //  assert(res == used.size());
  119.  
  120.     while ( mtr.n * mtr.m != 1 )
  121.     {
  122.         if(mtr.n >= mtr.m)
  123.             mtr = mtr.vertical_fold();
  124.         else
  125.             mtr = mtr.horizontal_fold();
  126.  
  127.         if(mtr.dr*(mtr.n-1) == 0 && mtr.dc*(mtr.m-1) == 0)
  128.             res++;
  129.         else
  130.         {
  131.             Range r;
  132.             if(mtr.dr == 0)
  133.                 r=Range(mtr.a00, mtr.a00+mtr.dc*(mtr.m-1), mtr.dc);
  134.             else
  135.                 r=Range(mtr.a00, mtr.a00+mtr.dr*(mtr.n-1), mtr.dr);
  136.  
  137.             ll lb = r.l;
  138.             ll rb = r.r;
  139.             ll st = r.step;
  140.  
  141.             for(Range range: ranges)
  142.             {
  143.                 ll cl = range.l;
  144.                 ll cr = range.r;
  145.                 ll s2 = range.step;
  146.  
  147.                 assert(cl <= lb);
  148.                 assert(cr <= rb);
  149.  
  150.                 if((lb-cl)%s2 != 0) continue;
  151.  
  152.                 ll k = (lb-cl)/s2 % (st/s2) ;
  153.                 cl += k*s2;
  154.                 assert(cl%st == lb % st);
  155.  
  156.                 k = (rb-cr)/s2 % (st/s2) ;
  157.                 cr += k*s2;
  158.                 if(k>0)
  159.                     cr -= st;
  160.  
  161.                 if(cl<=cr)
  162.                 {
  163.                     assert( (cr < lb) || (cl<=lb && cr<=rb) );
  164.                     if(cr>=lb)
  165.                         lb = cr+st;
  166.                 }
  167.             }
  168.  
  169.             if(lb<=rb)
  170.                 res+= (rb-lb+st)/st;
  171.             ranges.push_back(r);
  172.  
  173. //          for(int i=0;i<n;i++)
  174. //              for(int j=0;j<m;j++)
  175. //                  used.insert(mtr.a00 + i * mtr.dr + j * mtr.dc);
  176. //          assert(res == used.size());
  177.         }
  178.     }
  179.  
  180.     return res;
  181. }
  182.  
  183. int main()
  184. {
  185. //  for(int i=0;i<=8;i++)
  186. //      for(int j=0;i+j<=8;j++)
  187. //          printf("%d %d %lld\n", 1<<i, 1<<j, solve(1<<i,1<<j));
  188.  
  189.     int n,m;
  190.     scanf("%d%d",&n,&m);
  191.  
  192.  
  193.     printf("%lld\n", solve(n,m));
  194.  
  195. //  vector<vector<int> > v(n, vector<int> (m));
  196. //  for(int i=0;i<n;i++)
  197. //      for(int j=0;j<m;j++)
  198. //          v[i][j] = i*m+j+1;
  199. //
  200. //  print_matrix(v);
  201. //  while(v.size() * v[0].size()>1)
  202. //  {
  203. //      if( v.size() >= v[0].size() )
  204. //          v = horizontal_fold(v);
  205. //      else
  206. //          v = vertical_fold(v);
  207. //      print_matrix(v);
  208. //  }
  209.  
  210.     return 0;
  211. }
  212.  
Advertisement
Add Comment
Please, Sign In to add comment