제출 #854547

#제출 시각아이디문제언어결과실행 시간메모리
854547Nhoksocqt1Nuclearia (CEOI15_nuclearia)C++17
100 / 100
370 ms153428 KiB
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define sz(x) int((x).size()) #define fi first #define se second typedef long long ll; typedef pair<int, int> ii; template<class X, class Y> inline bool maximize(X &x, const Y &y) {return (x < y ? x = y, 1 : 0);} template<class X, class Y> inline bool minimize(X &x, const Y &y) {return (x > y ? x = y, 1 : 0);} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int Random(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); } const int MAXN = 200005; const int MAXM = 2500006; const int SQRT = 1600; struct Point { int x, y, a, b; } p[MAXN]; struct Query { int x, y, u, v; } qr[MAXN]; vector<ll> sum[SQRT], f[SQRT], g[SQRT]; ll dpl[MAXM], dplt[MAXM], dpr[MAXM], dprt[MAXM]; int row, col, nArr, numQuery; inline void addRec(int x, int y, int u, int v, int w) { sum[x][y] += w; sum[u + 1][y] -= w; sum[x][v + 1] -= w; sum[u + 1][v + 1] += w; } void brute(void) { for (int i = 0; i <= row + 1; ++i) sum[i].assign(col + 2, 0); for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); d = max({x - max(x - d, 1), y - max(y - d, 1), min(x + d, row) - x, min(y + d, col) - y}); for (int j = 0; j <= d; ++j) { int x1 = max(x - j, 1), y1 = max(y - j, 1), u1 = min(x + j, row), v1 = min(y + j, col); addRec(x1, y1, u1, v1, (j < d ? +1LL * b * (j + 1) : 0LL) - 1LL * b * j); if(j == d) addRec(x1, y1, u1, v1, a); } } for (int x = 1; x <= row; ++x) { for (int y = 1; y <= col; ++y) { sum[x][y] += sum[x - 1][y] + sum[x][y - 1] - sum[x - 1][y - 1]; } } for (int x = 1; x <= row; ++x) { for (int y = 1; y <= col; ++y) { sum[x][y] += sum[x - 1][y] + sum[x][y - 1] - sum[x - 1][y - 1]; } } for (int t = 0; t < numQuery; ++t) { int x(qr[t].x), y(qr[t].y), u(qr[t].u), v(qr[t].v), sizen = (u - x + 1) * (v - y + 1); ll totRad = sum[u][v] - sum[u][y - 1] - sum[x - 1][v] + sum[x - 1][y - 1]; cout << totRad / sizen + (totRad % sizen >= (sizen + 1) / 2) << '\n'; } } void subrow1(void) { for (int i = 0; i <= row + 1; ++i) sum[i].assign(col + 2, 0); for (int i = 1; i <= nArr; ++i) { int y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); sum[1][max(y - d, 1)] += a; sum[1][min(y + d, col) + 1] -= a; dpl[y - 1] -= b; if(y > d + 1) { dpl[y - d - 1] += b; dplt[y - d - 1] += 1LL * b * d; } dpr[y + 1] -= b; if(y + d + 1 <= col) { dpr[y + d + 1] += b; dprt[y + d + 1] += 1LL * b * d; } } for (int i = 1; i <= col; ++i) sum[1][i] += sum[1][i - 1]; ll sumn(0), add(0); for (int i = col; i > 0; --i) { add += dpl[i]; sumn += add + dplt[i]; sum[1][i] += sumn; } add = sumn = 0; for (int i = 1; i <= col; ++i) { add += dpr[i]; sumn += add + dprt[i]; sum[1][i] += sumn + sum[1][i - 1]; } for (int t = 0; t < numQuery; ++t) { int x(qr[t].x), y(qr[t].y), u(qr[t].u), v(qr[t].v), sizen = (u - x + 1) * (v - y + 1); ll totRad = sum[u][v] - sum[u][y - 1] - sum[x - 1][v] + sum[x - 1][y - 1]; cout << totRad / sizen + (totRad % sizen >= (sizen + 1) / 2) << '\n'; } } void magicFunc(void) { for (int i = 0; i <= row + 1; ++i) { sum[i].assign(col + 2, 0); f[i].assign(col + 2, 0); g[i].assign(col + 2, 0); } for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); sum[max(x - d, 1)][max(y - d, 1)] += a; sum[max(x - d, 1)][min(y + d, col) + 1] -= a; sum[min(x + d, row) + 1][max(y - d, 1)] -= a; sum[min(x + d, row) + 1][min(y + d, col) + 1] += a; sum[x][y] += b; sum[x + 1][y + 1] += b; sum[x + 1][y] -= b; sum[x][y + 1] -= b; } for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); int z = max(1, min(d, max(x, y) - 1)); f[max(1, x - 1)][max(1, y - 1)] += b; g[max(1, x - z)][max(1, y - z)] -= 1LL * b * (z + 1); if(x - d - 1 < 1 && y - d - 1 < 1) continue; f[max(1, x - d - 1)][max(1, y - d - 1)] -= b; } for (int i = row; i > 0; --i) { for (int j = col; j > 0; --j) { sum[i][j] += g[i][j] + f[i][j]; f[max(1, i - 1)][max(1, j - 1)] += f[i][j]; f[i][j] = g[i][j] = 0; } } for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); ++x, ++y; if(x >= row || y >= col) continue; f[min(row, x + 1)][min(col, y + 1)] += b; if(x + d <= row && y + d <= col) g[min(row, x + d)][min(col, y + d)] -= 1LL * b * (d + 1); if(x + d + 1 > row || y + d + 1 > col) continue; f[min(row, x + d + 1)][min(col, y + d + 1)] -= b; } for (int i = 1; i <= row; ++i) { for (int j = 1; j <= col; ++j) { sum[i][j] += g[i][j] + f[i][j]; f[min(row + 1, i + 1)][min(col + 1, j + 1)] += f[i][j]; f[i][j] = g[i][j] = 0; } } for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); ++x; if(x >= row) continue; f[min(row, x + 1)][max(1, y - 1)] -= b; if(x + d <= row) g[min(row, x + d)][max(1, y - d)] += 1LL * b * (d + 1); if(x + d + 1 > row) continue; f[min(row, x + d + 1)][max(1, y - d - 1)] += b; } for (int i = 1; i <= row; ++i) { for (int j = col; j > 0; --j) { sum[i][j] += g[i][j] + f[i][j]; f[min(row + 1, i + 1)][max(1, j - 1)] += f[i][j]; f[i][j] = g[i][j] = 0; } } for (int i = 1; i <= nArr; ++i) { int x(p[i].x), y(p[i].y), a(p[i].a), b(p[i].b), d(a / b); ++y; if(y >= col) continue; f[max(1, x - 1)][min(col, y + 1)] -= b; if(y + d <= col) g[max(1, x - d)][min(col, y + d)] += 1LL * b * (d + 1); if(y + d + 1 > col) continue; f[max(1, x - d - 1)][min(col, y + d + 1)] += b; } for (int i = row; i > 0; --i) { for (int j = 1; j <= col; ++j) { sum[i][j] += g[i][j] + f[i][j]; f[max(1, i - 1)][min(col + 1, j + 1)] += f[i][j]; f[i][j] = g[i][j] = 0; } } /*for (int i = 1; i <= row; ++i) { for (int j = 1; j <= col; ++j) { cout << sum[i][j] << " \n"[j == col]; } } cout << '\n';*/ for (int i = 1; i <= row; ++i) { for (int j = 1; j <= col; ++j) { sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]; //cout << sum[i][j] << " \n"[j == col]; } } for (int i = 1; i <= row; ++i) { for (int j = 1; j <= col; ++j) { sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]; //cout << sum[i][j] << " \n"[j == col]; } } for (int t = 0; t < numQuery; ++t) { int x(qr[t].x), y(qr[t].y), u(qr[t].u), v(qr[t].v), sizen = (u - x + 1) * (v - y + 1); ll totRad = sum[u][v] - sum[u][y - 1] - sum[x - 1][v] + sum[x - 1][y - 1]; cout << totRad / sizen + (totRad % sizen >= (sizen + 1) / 2) << '\n'; } } void process() { cin >> row >> col >> nArr; bool isSwapped = (row > col); if(isSwapped) swap(row, col); ll sumf(0); for (int i = 1; i <= nArr; ++i) { cin >> p[i].x >> p[i].y >> p[i].a >> p[i].b; //p[i].x = Random(1, row), p[i].y = Random(1, col), p[i].a = Random(1, 1000), p[i].b = Random(1, 1000); cout << p[i].x << ' ' << p[i].y << ' ' << p[i].a << ' ' << p[i].b << '\n'; p[i].b = min(p[i].b, p[i].a); if(isSwapped) swap(p[i].x, p[i].y); int x(p[i].x), y(p[i].y), d(p[i].a / p[i].b); sumf += max({x - max(1, x - d), y - max(1, y - d), min(row, x + d) - x, min(col, y + d) - y}) + 1; } cin >> numQuery; for (int t = 0; t < numQuery; ++t) { cin >> qr[t].x >> qr[t].y >> qr[t].u >> qr[t].v; //qr[t].x = Random(1, row), qr[t].y = Random(1, col), qr[t].u = Random(qr[t].x, row), qr[t].v = Random(qr[t].y, col); cout << qr[t].x << ' ' << qr[t].y << ' ' << qr[t].u << ' ' << qr[t].v << '\n'; if(isSwapped) { swap(qr[t].x, qr[t].y); swap(qr[t].u, qr[t].v); } } if(1LL * nArr * row * col <= 1e8 || sumf <= 1e7) { brute(); } else if(row == 1) { subrow1(); } else { magicFunc(); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); process(); return 0; }
#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...
#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...