prog3r

TL https://basecamp.eolymp.com/en/problems/11863

Jul 14th, 2025
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.95 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. signed main() {
  5.     ios::sync_with_stdio(0);
  6.     cin.tie(0);
  7.     int T;
  8.     cin >> T;
  9.     for (int tt = 0; tt < T; tt += 1) {
  10.         int n, m;
  11.         cin >> n >> m;
  12.         vector<vector<int>> a(n, vector<int>(m));
  13.         for (auto &x : a) {
  14.             for (auto &y : x) {
  15.                 cin >> y;
  16.             }
  17.         }
  18.         int q;
  19.         cin >> q;
  20.         // [к какой стенке][куда идет треугольник ч1 (нлвп)][куда идет треугольник ч2: += по той коорде которая меняется или -= ]
  21.         vector<vector<vector<vector<vector<int>>>>> SU(4, vector<vector<vector<vector<int>>>>(4, vector<vector<vector<int>>>(2, vector<vector<int>>(n, vector<int>(m)))));
  22.         vector<vector<vector<vector<vector<int>>>>> SU_A(4, vector<vector<vector<vector<int>>>>(4, vector<vector<vector<int>>>(2, vector<vector<int>>(n, vector<int>(m)))));
  23.         vector<vector<vector<int>>> R(4, vector<vector<int>>(n, vector<int>(m)));
  24.         vector<vector<vector<int>>> R_A(4, vector<vector<int>>(n, vector<int>(m)));
  25.         auto val = [&] (int type, int i, int j) -> int {
  26.             if (type == 0) {
  27.                 return n-i;
  28.             }
  29.             if (type == 1) {
  30.                 return j+1;
  31.             }
  32.             if (type == 2) {
  33.                 return i+1;
  34.             }
  35.             if (type == 3) {
  36.                 return m-j;
  37.             }
  38.             assert(false);
  39.         };
  40.         for (int k = 0; k < 4; k += 1) {
  41.             for (int i = 0; i < n; i += 1) {
  42.                 for (int j = 0; j < m; j += 1) {
  43.                     R[k][i][j] = val(k, i, j)*a[i][j];
  44.                     R_A[k][i][j] = a[i][j];
  45.                     if (i) {
  46.                         R[k][i][j] += R[k][i-1][j];
  47.                         R_A[k][i][j] += R_A[k][i-1][j];
  48.                     }
  49.                     if (j) {
  50.                         R[k][i][j] += R[k][i][j-1];
  51.                         R_A[k][i][j] += R_A[k][i][j-1];
  52.                     }
  53.                     if (i && j) {
  54.                         R[k][i][j] -= R[k][i-1][j-1];
  55.                         R_A[k][i][j] -= R_A[k][i-1][j-1];
  56.                     }
  57.                 }
  58.             }
  59.         }
  60.         auto rect_sum = [&] (const vector<vector<int>>& v, int lr, int lc, int rr, int rc) -> int {
  61.             lr = max(lr, 0ll);
  62.             lc = max(lc, 0ll);
  63.             rr = min(rr, n-1);
  64.             rc = min(rc, m-1);
  65.             if (lr > rr || lc > rc) {
  66.                 return 0;
  67.             }
  68.             int ans = v[rr][rc];
  69.             ans -= lc?v[rr][lc-1]:0;
  70.             ans -= lr?v[lr-1][rc]:0;
  71.             ans += lc&&lr?v[lr-1][lc-1]:0;
  72.             return ans;
  73.         };
  74.         auto valid = [&] (int i, int j) -> bool {
  75.             return i>=0&&i<n&&j>=0&&j<m;
  76.         };
  77.         for (int k = 0; k < 4; k += 1) {
  78.             for (int i = n-1; i >= 0; i -= 1) {
  79.                 for (int j = 0; j < m; j += 1) {
  80.                     SU[k][0][0][i][j] = SU[k][0][1][i][j] = rect_sum(R[k], i, j, n-1, j);
  81.                     SU_A[k][0][0][i][j] = SU_A[k][0][1][i][j] = rect_sum(R_A[k], i, j, n-1, j);
  82.                     if (valid(i+1, j+1)) {
  83.                         SU[k][0][1][i][j] += SU[k][0][1][i+1][j+1];
  84.                         SU_A[k][0][1][i][j] += SU_A[k][0][1][i+1][j+1];
  85.                     }
  86.                     if (valid(i+1, j-1)) {
  87.                         SU[k][0][0][i][j] += SU[k][0][0][i+1][j-1];
  88.                         SU_A[k][0][0][i][j] += SU_A[k][0][0][i+1][j-1];
  89.                     }
  90.                 }
  91.             }
  92.             for (int i = 0; i < n; i += 1) {
  93.                 for (int j = 0; j < m; j += 1) {
  94.                     SU[k][2][0][i][j] = SU[k][2][1][i][j] = rect_sum(R[k], 0, j, i, j);
  95.                     SU_A[k][2][0][i][j] = SU_A[k][2][1][i][j] = rect_sum(R_A[k], 0, j, i, j);
  96.                     if (valid(i-1, j+1)) {
  97.                         SU[k][2][1][i][j] += SU[k][2][1][i-1][j+1];
  98.                         SU_A[k][2][1][i][j] += SU_A[k][2][1][i-1][j+1];
  99.                     }
  100.                     if (valid(i-1, j-1)) {
  101.                         SU[k][2][0][i][j] += SU[k][2][0][i-1][j-1];
  102.                         SU_A[k][2][0][i][j] += SU_A[k][2][0][i-1][j-1];
  103.                     }
  104.                 }
  105.             }
  106.             for (int j = 0; j < m; j += 1) {
  107.                 for (int i = 0; i < n; i += 1) {
  108.                     SU[k][1][0][i][j] = SU[k][1][1][i][j] = rect_sum(R[k], i, 0, i, j);
  109.                     SU_A[k][1][0][i][j] = SU_A[k][1][1][i][j] = rect_sum(R_A[k], i, 0, i, j);
  110.                     if (valid(i+1, j-1)) {
  111.                         SU[k][1][1][i][j] += SU[k][1][1][i+1][j-1];
  112.                         SU_A[k][1][1][i][j] += SU_A[k][1][1][i+1][j-1];
  113.                     }
  114.                     if (valid(i-1, j-1)) {
  115.                         SU[k][1][0][i][j] += SU[k][1][0][i-1][j-1];
  116.                         SU_A[k][1][0][i][j] += SU_A[k][1][0][i-1][j-1];
  117.                     }
  118.                 }
  119.             }
  120.             for (int j = m-1; j >= 0; j -= 1) {
  121.                 for (int i = 0; i < n; i += 1) {
  122.                     SU[k][3][0][i][j] = SU[k][3][1][i][j] = rect_sum(R[k], i, j, i, m-1);
  123.                     SU_A[k][3][0][i][j] = SU_A[k][3][1][i][j] = rect_sum(R_A[k], i, j, i, m-1);
  124.                     if (valid(i+1, j+1)) {
  125.                         SU[k][3][1][i][j] += SU[k][3][1][i+1][j+1];
  126.                         SU_A[k][3][1][i][j] += SU_A[k][3][1][i+1][j+1];
  127.                     }
  128.                     if (valid(i-1, j+1)) {
  129.                         SU[k][3][0][i][j] += SU[k][3][0][i-1][j+1];
  130.                         SU_A[k][3][0][i][j] += SU_A[k][3][0][i-1][j+1];
  131.                     }
  132.                 }
  133.             }
  134.         }
  135.         vector<function<int(int, int, int, int, const vector<vector<int>>, const vector<vector<int>>&)>> f = {
  136.                 [&] (int r, int c, int end, int mnozh, const vector<vector<int>>& s, const vector<vector<int>>& rect) -> int {
  137.                     return s[r][c] - (valid(end+1, c+(end-r)*mnozh+mnozh)?s[end+1][c+(end-r)*mnozh+mnozh]:0) - (mnozh==-1?rect_sum(rect, end+1, c+(end-r)*mnozh, n-1, c):rect_sum(rect, end+1, c, n-1, c+(end-r)*mnozh));
  138.                 },
  139.                 [&] (int r, int c, int end, int mnozh, const vector<vector<int>>& s, const vector<vector<int>>& rect) -> int {
  140.                     return s[r][c] - (valid(r+(c-end)*mnozh+mnozh, end-1)?s[r+(c-end)*mnozh+mnozh][end-1]:0) - (mnozh==-1?rect_sum(rect, r+(c-end)*mnozh, 0, r, end-1):rect_sum(rect, r, 0, r+(c-end)*mnozh, end-1));
  141.                 },
  142.                 [&] (int r, int c, int end, int mnozh, const vector<vector<int>>& s, const vector<vector<int>>& rect) -> int {
  143.                     return s[r][c] - (valid(end-1, c+(r-end)*mnozh+mnozh)?s[end-1][c+(r-end)*mnozh+mnozh]:0) - (mnozh==-1?rect_sum(rect, 0, c+(r-end)*mnozh, end-1, c):rect_sum(rect, 0, c, end-1, c+(r-end)*mnozh));
  144.                 },
  145.                 [&] (int r, int c, int end, int mnozh, const vector<vector<int>>& s, const vector<vector<int>>& rect) -> int {
  146.                     return s[r][c] - (valid(r+(end-c)*mnozh+mnozh, end+1)?s[r+(end-c)*mnozh+mnozh][end+1]:0) - (mnozh==-1?rect_sum(rect, r+(end-c)*mnozh, end+1, r, m-1):rect_sum(rect, r, end+1, r+(end-c)*mnozh, m-1));
  147.                 }
  148.         };
  149.         // 0 = down, 1 = left, 2 = up, 3 = right
  150.         auto treug = [&] (int r, int c, int end, int i, int j, int k) -> int {
  151.             int mnozh = k?1:-1;
  152.             int cancel=i==0?n-1-r:i==3?m-1-c:i==2?r:c;
  153.             return f[j](r, c, end, mnozh, SU[i][j][k], R[i]) - f[j](r, c, end, mnozh, SU_A[i][j][k], R_A[i])*cancel;
  154.         };
  155.         for (int ii = 0; ii < q; ii += 1) {
  156.             int lr, lc, rr, rc;
  157.             cin >> lr >> lc >> rr >> rc;
  158.             lr -= 1, rr -= 1, lc -= 1, rc -= 1;
  159. //            lr = mt()%n;
  160. //            rr = mt()%(n-lr)+lr;
  161. //            lc = mt()%m;
  162. //            rc = mt()%(m-lc)+lc;
  163. //            cout << ii << " " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()-start).count() << endl;
  164.             int w = rc - lc + 1;
  165.             int h = rr - lr + 1;
  166.             int C = min(h/2, w/2);
  167.             if (h <= w) {
  168.                 int levo = (h>2?treug(rr-1, lc, rr-C+((min(h, w)&1)==0), 1, 2, 1):0) + (h>3?treug(lr+1, lc, lr+C-1, 1, 0, 1):0);
  169.                 int pravo = (h>2?treug(rr-1, rc, rr-C+((min(h, w)&1)==0), 3, 2, 0):0) + (h>3?treug(lr+1, rc, lr+C-1, 3, 0, 0):0);
  170.                 int niz = treug(rr, rc, rc+1-C, 0, 1, 0) + treug(rr, lc, lc-1+C, 0, 3, 0);
  171.                 niz += rect_sum(R[0], lr+C, lc+C, rr, rc-C)-rect_sum(R_A[0], lr+C, lc+C, rr, rc-C)*(n-1-rr);
  172.                 int ans = levo+pravo+niz;
  173.                 if (h > 1) {
  174.                     int verh = treug(lr, lc, lc-1+C, 2, 3, 1) + treug(lr, rc, rc+1-C, 2, 1, 1);
  175.                     verh += rect_sum(R[2], lr, lc+C, lr+C-1, rc-C) - rect_sum(R_A[2], lr, lc+C, lr+C-1, rc-C)*(lr);
  176.                     ans += verh;
  177.                 }
  178.                 cout << ans << "\n";
  179.             } else {
  180.                 int niz = (w>2?treug(rr, rc-1, rc-C+((min(h, w)&1)==0), 0, 1, 0):0) + (w>3?treug(rr, lc+1, lc+C-1, 0, 3, 0):0);
  181.                 int verh = (w>2?treug(lr, lc+1, lc+C-((min(h, w)&1)==0), 2, 3, 1):0) + (w>3?treug(lr, rc-1, rc-C+1, 2, 1, 1):0);
  182.                 int levo = treug(rr, lc, rr+1-C, 1, 2, 1) + treug(lr, lc, lr-1+C, 1, 0, 1);
  183.                 levo += rect_sum(R[1], lr+C, lc, rr-C, rc-C)-rect_sum(R_A[1], lr+C, lc, rr-C, rc-C)*(lc);
  184.                 int ans = niz+verh+levo;
  185.                 if (w > 1) {
  186.                     int pravo = treug(rr, rc, rr+1-C, 3, 2, 0) + treug(lr, rc, lr-1+C, 3, 0, 0);
  187.                     pravo += rect_sum(R[3], lr+C, rc-C+1, rr-C, rc)-rect_sum(R_A[3], lr+C, rc-C+1, rr-C, rc)*(m-1-rc);
  188.                     ans += pravo;
  189.                 }
  190.                 cout << ans << "\n";
  191.             }
  192.         }
  193.     }
  194. }
Advertisement
Add Comment
Please, Sign In to add comment