Submission #1241089

#TimeUsernameProblemLanguageResultExecution timeMemory
1241089madamadam3Mosaic (IOI24_mosaic)C++20
22 / 100
781 ms302376 KiB
#include "mosaic.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; using vi =vector<int>; using vl = vector<ll>; using vvi = vector<vi>; using vvl = vector<vl>; using pi = pair<int, int>; using vpi = vector<pi>; #ifdef LOCAL #define dout std::cout #else #define dout if (0) std::cout #endif #define pb push_back #define lb lower_bound #define ub upper_bound #define all(x) (x).begin(), (x).end() #define en(x) (x).end() #define bg(x) (x).begin() #define rev(x) reverse(all(x)) #define sz(x) int((x).size()) #define FOR(i, a, b) for (int i = a; i < b; i++) #define each(a, x) for (auto &a : x) #define trace(x) for (auto &el : x) dout << el << " " vl mosaic(vi X, vi Y, vi T, vi B, vi L, vi R) { int Q = sz(T), n = sz(X); if (n <= 5000) { vl C(Q, 0); vvi grid(n, vi(n, 0)); FOR(i, 0, n) { grid[0][i] = X[i]; grid[i][0] = Y[i]; } FOR(i, 1, n) { FOR(j, 1, n) { if (grid[i-1][j] == 0 && grid[i][j-1] == 0) grid[i][j] = 1; else grid[i][j] = 0; } } vvl pref(n+1, vl(n+1, 0)); FOR(i, 0, n) { FOR(j, 0, n) { pref[i+1][j+1] = grid[i][j] + pref[i+1][j]; } FOR(j, 0, n) { pref[i+1][j+1] += pref[i][j+1]; } } // vl prefx(n+1, 0); FOR(i, 0, n) prefx[i+1] = prefx[i] + X[i]; FOR(qn, 0, Q) { int x1 = T[qn], x2 = B[qn], y1 = L[qn], y2 = R[qn]; // C[qn] = prefx[y2+1] - prefx[y1]; C[qn] += pref[x2+1][y2+1]; C[qn] += pref[x1][y1]; C[qn] -= pref[x1][y2+1]; C[qn] -= pref[x2+1][y1]; } return C; } vl C(Q, 0); vvi grid(n, vi(3, 0)); grid[0].resize(n); grid[1].resize(n); grid[2].resize(n); FOR(i, 0, n) { grid[0][i] = X[i]; grid[i][0] = Y[i]; } map<pi, int> coord; map<int, pi> revcoord; int cc = 0; for (int i = n - 1; i >= 3; i--) { coord[{i, 2}] = cc++; revcoord[cc-1] = {i, 2}; } for (int i = 2; i < n; i++) { coord[{2, i}] = cc++; revcoord[cc-1] = {2, i}; } FOR(i, 1, n) { int top = i <= 2 ? n : 3; FOR(j, 1, top) { if (grid[i-1][j] == 0 && grid[i][j-1] == 0) grid[i][j] = 1; else grid[i][j] = 0; } } vl pref(cc+1, 0); FOR(i, 0, cc) pref[i+1] = pref[i] + grid[revcoord[i].first][revcoord[i].second]; vl wpref(cc+1, 0); FOR(i, 1, cc+1) wpref[i] = wpref[i-1] + i * grid[revcoord[i-1].first][revcoord[i-1].second]; vl wrpref(cc+1, 0); FOR(i, 1, cc+1) wrpref[i] = wrpref[i-1] + i * grid[revcoord[cc-i].first][revcoord[cc-i].second]; vvl prefix(n+1, vl(4, 0)); prefix[0].resize(n+1); prefix[1].resize(n+1); prefix[2].resize(n+1); prefix[3].resize(n+1); FOR(i, 0, n) { int top = i < 3 ? n : 3; FOR(j, 0, top) { prefix[i+1][j+1] = grid[i][j] + prefix[i+1][j]; } FOR(j, 0, top) { prefix[i+1][j+1] += prefix[i][j+1]; } } auto get_ramp_up = [&](int u, int len) { int v = u + len - 1; ll sumVal = pref[v+1] - pref[u]; ll sum_iVal = (wpref[v+1] - wpref[u]) - sumVal; return sum_iVal - ll(u-1) * sumVal; }; auto get_ramp_down = [&](int e, int len) { int s = e - len + 1; ll sumVal = pref[e+1] - pref[s]; ll sum_iVal = (wpref[e+1] - wpref[s]) - sumVal; return sum_iVal + ll(len - e) * sumVal; }; for (int qn = 0; qn < Q; ++qn) { int x1 = T[qn], x2 = B[qn]; int y1 = L[qn], y2 = R[qn]; ll res = 0; if (x1 <= 2) { int r = min(x2, 2); res += prefix[r+1][y2+1] - prefix[r+1][y1] - prefix[x1][y2+1] + prefix[x1][y1]; } if (y1 <= 2) { int c = min(y2, 2); res += prefix[x2+1][c+1] - prefix[x1][c+1] - prefix[x2+1][y1] + prefix[x1][y1]; } if (x1 <= 2 && y1 <= 2) { res -= prefix[x1][y1]; } int cx = max(x1, 3), cy = max(y1, 3); if (cx <= x2 && cy <= y2) { int diagLen = min(x2 - cx, y2 - cy) + 1; int sx = cx - (diagLen - 1), sy = cy - (diagLen - 1); int ex = cx, ey = cy; int lc = coord[{sx, sy}], rc = coord[{ex, ey}]; ll rise = get_ramp_up(lc, diagLen); ll flat = 0; int fl = lc + diagLen, fr = rc - diagLen; if (fl <= fr) { ll cnt = fr - fl + 1; ll segment= pref[fr+1] - pref[fl]; flat = cnt * segment; } ll fall = get_ramp_down(rc, diagLen); res += rise + flat + fall; } C[qn] = res; } return C; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...