Submission #1314075

#TimeUsernameProblemLanguageResultExecution timeMemory
1314075Zero_OPMosaic (IOI24_mosaic)C++20
100 / 100
212 ms207588 KiB
#include "mosaic.h" #include <bits/stdc++.h> using namespace std; bool BEGIN_ALLOC; #define FOR(i, l, r) for(int i = (l); i < (r); ++i) #define F0R(i, r) FOR(i, 0, r) #define all(v) begin(v), end(v) #define rall(v) rbegin(v), rend(v) #define sz(v) (int)v.size() #define pb push_back #define eb emplace_back #define ff first #define ss second #define mp make_pair #define mt make_tuple #define tcT template<class T tcT> bool minimize(T& a, const T& b){ return (a > b ? a = b, 1 : 0); } tcT> bool maximize(T& a, const T& b){ return (a < b ? a = b, 1 : 0); } using ll = long long; using db = double; using ull = unsigned long long; using pi = pair<int, int>; using pl = pair<ll, ll>; using vi = vector<int>; using vl = vector<ll>; using vpi = vector<pi>; using vpl = vector<pl>; std::vector<long long> mosaic124(std::vector<int> X, std::vector<int> Y, std::vector<int> T, std::vector<int> B, std::vector<int> L, std::vector<int> R) { int N = sz(X), Q = sz(T); vector<vi> pref(N, vi(N)), a(N, vi(N)); F0R(i, N){ pref[0][i] = a[0][i] = X[i]; pref[i][0] = a[i][0] = Y[i]; } F0R(i, N){ F0R(j, N){ if(i > 0 && j > 0){ a[i][j] = (a[i - 1][j] == 0 && a[i][j - 1] == 0 ? 1 : 0); } pref[i][j] = a[i][j]; if(i > 0) pref[i][j] += pref[i - 1][j]; if(j > 0) pref[i][j] += pref[i][j - 1]; if(i > 0 && j > 0) { pref[i][j] -= pref[i - 1][j - 1]; } } } auto sumRect = [&](int a, int b, int c, int d){ return pref[c][d] - (b == 0 ? 0 : pref[c][b - 1]) - (a == 0 ? 0 : pref[a - 1][d]) + (a == 0 || b == 0 ? 0 : pref[a - 1][b - 1]); }; vl ans(Q); F0R(i, Q){ ans[i] = sumRect(T[i], L[i], B[i], R[i]); } return ans; } std::vector<long long> mosaic6(std::vector<int> X, std::vector<int> Y, std::vector<int> T, std::vector<int> B, std::vector<int> L, std::vector<int> R) { int N = sz(X), Q = sz(T); vector<vi> a(N), pref(N); F0R(i, N){ if(i < 3){ a[i].resize(N); } else{ a[i].resize(3); } if(i == 0) a[i] = X; a[i][0] = Y[i]; if(i > 0){ FOR(j, 1, sz(a[i])){ a[i][j] = (a[i - 1][j] == 0 && a[i][j - 1] == 0); } } // F0R(j, sz(a[i])){ // pref[i][j] = a[i][j]; // if(i > 0) pref[i][j] += pref[i - 1][j]; // if(j > 0) pref[i][j] += pref[i][j - 1]; // if(i > 0 && j > 0) pref[i][j] -= pref[i - 1][j - 1]; // } } // cerr << "preprocess ! \n"; auto querySingle = [&](int x, int y){ // cerr << "wtf " << x << ' ' << y << '\n'; if(min(x, y) < 3){ return a[x][y]; } if(x <= y){ int ret = x - 2; // cerr << x - ret << ' ' << y - ret << " !\n"; return a[x - ret][y - ret]; } else{ int ret = y - 2; return a[x - ret][y - ret]; } }; vl ans(Q); auto query = [&](int a, int b, int c, int d){ if(a == c && b == d) return querySingle(a, b); return 0; }; F0R(i, Q){ ans[i] = query(T[i], L[i], B[i], R[i]); } return ans; } std::vector<long long> mosaic(std::vector<int> X, std::vector<int> Y, std::vector<int> T, std::vector<int> B, std::vector<int> L, std::vector<int> R) { if(sz(X) <= 5000) return mosaic124(X, Y, T, B, L, R); if(L == R && T == B) return mosaic6(X, Y, T, B, L, R); int N = sz(X), Q = sz(T); vector<vi> a(N), pref(N); F0R(i, N){ if(i < 3){ a[i].resize(N); pref[i].resize(N); } else{ a[i].resize(3); pref[i].resize(3); } if(i == 0) a[i] = X; a[i][0] = Y[i]; if(i > 0){ FOR(j, 1, sz(a[i])){ a[i][j] = (a[i - 1][j] == 0 && a[i][j - 1] == 0); } } F0R(j, sz(a[i])){ pref[i][j] = a[i][j]; if(i > 0) pref[i][j] += pref[i - 1][j]; if(j > 0) pref[i][j] += pref[i][j - 1]; if(i > 0 && j > 0) pref[i][j] -= pref[i - 1][j - 1]; } } auto querySingle = [&](int x, int y){ // cerr << "wtf " << x << ' ' << y << '\n'; if(min(x, y) < 3){ return a[x][y]; } if(x <= y){ int ret = x - 2; // cerr << x - ret << ' ' << y - ret << " !\n"; return a[x - ret][y - ret]; } else{ int ret = y - 2; return a[x - ret][y - ret]; } }; vl ans(Q); vl row2, col2; FOR(i, 2, N) { row2.pb(a[2][i]); col2.pb(a[i][2]); } vl sumRow(sz(row2)), sumCol(sz(col2)); vl sumRowMul(sz(row2)), sumColMul(sz(col2)); F0R(i, sz(row2)){ sumRow[i] = (i > 0 ? sumRow[i - 1] : 0) + row2[i]; sumCol[i] = (i > 0 ? sumCol[i - 1] : 0) + col2[i]; sumRowMul[i] = (i > 0 ? sumRowMul[i - 1] : 0) + row2[i] * i; sumColMul[i] = (i > 0 ? sumColMul[i - 1] : 0) + col2[i] * i; } auto sumRev = [&](vl& sum, vl& sumMul, int n){ return (n + 1) * sum[n] - sumMul[n]; }; function<ll(int, int)> solveUpperTriangle = [&](int n, int m){ if(n == m) return sumRev(sumRow, sumRowMul, n); if(n <= m){ ll ans = sumRev(sumRow, sumRowMul, m); ans -= solveUpperTriangle(m - n - 1, m - n - 1); return ans; } else{ ll ans = sumRev(sumRow, sumRowMul, m); return ans; } }; function<ll(int, int)> solveLowerTriangle = [&](int n, int m){ if(n == m) return sumRev(sumCol, sumColMul, n); if(n <= m){ return sumRev(sumCol, sumColMul, n); } else{ ll ans = sumRev(sumCol, sumColMul, n); ans -= solveLowerTriangle(n - m - 1, n - m - 1); return ans; } }; auto solveRect = [&](int n, int m){ if(n < 0 || m < 0) return 0ll; if(min(n, m) < 3) return 1LL * pref[n][m]; ll partL = pref[1][m] + pref[n][1] - pref[1][1]; ll partU = solveUpperTriangle(n - 2, m - 2); ll partD = solveLowerTriangle(n - 2, m - 2); ll diag = min(n - 1, m - 1) * a[2][2]; return partL + partU + partD - diag; }; auto query = [&](int a, int b, int c, int d){ ll v1 = solveRect(c, d); ll v2 = solveRect(a - 1, d); ll v3 = solveRect(c, b - 1); ll v4 = solveRect(a - 1, b - 1); return v1 - v2 - v3 + v4; }; F0R(i, Q){ ans[i] = query(T[i], L[i], B[i], R[i]); } return ans; } #ifdef LOCAL int main(){ freopen("task.inp", "r", stdin); freopen("task.out", "w", stdout); int N; cin >> N; vi X(N), Y(N); F0R(i, N) cin >> X[i]; F0R(i, N) cin >> Y[i]; int Q; cin >> Q; vi T(Q), B(Q), L(Q), R(Q); F0R(i, Q){ cin >> T[i] >> B[i] >> L[i] >> R[i]; } vl ans = mosaic(X, Y, T, B, L, R); for(auto x : ans) cout << x << ' '; return 0; } #endif //LOCAl
#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...