Advertisement
erek1e

IOI '06 P2 - Pyramid

Jun 25th, 2023
779
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <tuple>
  5.  
  6. using namespace std;
  7.  
  8. int main() {
  9.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  10.     int m, n, a, b, c, d;
  11.     cin >> m >> n >> a >> b >> c >> d;
  12.     vector<vector<int>> g(1+n, vector<int>(1+m));
  13.     for (int i = 1; i <= n; ++i) {
  14.         for (int j = 1; j <= m; ++j) {
  15.             int x; cin >> x;
  16.             g[i][j] += x;
  17.             if (j < m) g[i][j+1] += g[i][j];
  18.             g[i][j] += g[i-1][j];
  19.         }
  20.     }
  21.     auto rect = [&g](int r1, int c1, int r2, int c2) {
  22.         --r1, --c1;
  23.         return g[r2][c2] - g[r1][c2] - g[r2][c1] + g[r1][c1];
  24.     };
  25.     vector<vector<int>> A(1+n + 1-b, vector<int>(1+m + 1-a));
  26.     vector<vector<int>> B(1+n + 1-d, vector<int>(1+m + 1-c));
  27.     for (int i = 1; i <= n; ++i) {
  28.         for (int j = 1; j <= m; ++j) {
  29.             if (i <= n+1-b && j <= m+1-a) A[i][j] = rect(i, j, i+b-1, j+a-1);
  30.             if (i <= n+1-d && j <= m+1-c) B[i][j] = rect(i, j, i+d-1, j+c-1);
  31.         }
  32.     }
  33.  
  34.     int maxSum = 0;
  35.     int iBase = -1, jBase = -1, iChamber = -1, jChamber = -1;
  36.    
  37.     vector<set<pair<int, int>>> columnActive(1+m + 1-c);
  38.     for (int i = 2; i < 1+b-d; ++i) {
  39.         for (int j = 1; j <= m+1-c; ++j) columnActive[j].emplace(B[i][j], i);
  40.     }
  41.  
  42.     for (int i = 1; i <= n+1-b; ++i) {
  43.         set<tuple<int, int, int>> s;
  44.         for (int j = 2; j < 1+a-c; ++j) {
  45.             auto [sum, row] = *columnActive[j].begin();
  46.             s.emplace(sum, row, j);
  47.         }
  48.         for (int j = 1; j <= m+1-a; ++j) {
  49.             int baseSum = A[i][j];
  50.             tuple<int, int, int> t = *s.begin();
  51.             int chamberSum = get<0>(t);
  52.             int chamberI = get<1>(t), chamberJ = get<2>(t);
  53.             if (baseSum-chamberSum > maxSum) {
  54.                 maxSum = baseSum-chamberSum;
  55.                 iBase = i, jBase = j;
  56.                 iChamber = chamberI, jChamber = chamberJ;
  57.             }
  58.             if (j+1 <= m+1-a) { // update s
  59.                 auto [sum, row] = *columnActive[j+1].begin();
  60.                 s.erase({sum, row, j+1});
  61.                 tie(sum, row) = *columnActive[j+a-c].begin();
  62.                 s.emplace(sum, row, j+a-c);
  63.             }
  64.         }
  65.  
  66.         if (i+1 <= n+1-b) { // update columnActive
  67.             for (int j = 1; j <= m+1-c; ++j) {
  68.                 columnActive[j].erase({B[i+1][j], i+1});
  69.                 columnActive[j].insert({B[i+b-d][j], i+b-d});
  70.             }
  71.         }
  72.     }
  73.  
  74.     cout << jBase << ' ' << iBase << '\n' << jChamber << ' ' << iChamber << '\n';
  75.     return 0;
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement