0
1
mirror of https://git.sb/baoshuo/OI-codes.git synced 2024-11-30 20:36:26 +00:00
OI-codes/S2OJ/1602/data/std.cpp

244 lines
6.9 KiB (Stored with Git LFS)
C++

/*
Code by Alexandru Enache
Problem : maxq 2D
Complexity : O(n^2*m + q*n^2*log(m))
Memory : O(n^2*m)
*/
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <iomanip>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <time.h>
#include <unordered_map>
#include <vector>
using namespace std;
#include <iostream>
//#pragma warning(disable:4996)
//#include <fstream>
// ifstream cin("input"); ofstream cout("output");
const int MAXN = 10;
const int MAXM = 1e5;
const int MAXQ = 5000;
int n, m;
int v[MAXN + 5][MAXM + 5];
long long sp[MAXN + 5][MAXM + 5];
int q;
struct qry {
int tip, x, y, val, x1, y1, x2, y2;
} qr[MAXQ + 5];
struct NOD {
long long sp, stmax, drmax, smax;
};
vector<NOD> arb[MAXN + 1][MAXN + 1];
void read() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> v[i][j];
}
}
cin >> q;
for (int i = 1; i <= q; i++) {
cin >> qr[i].tip;
if (qr[i].tip == 1) {
cin >> qr[i].x >> qr[i].y >> qr[i].val;
}
if (qr[i].tip == 2) {
cin >> qr[i].x1 >> qr[i].y1 >> qr[i].x2 >> qr[i].y2;
}
}
}
void prop(int i, int j, int nod, int st, int dr) {
if (st == dr) {
arb[i][j][nod].sp = sp[j][st] - sp[i - 1][st];
arb[i][j][nod].stmax = sp[j][st] - sp[i - 1][st];
arb[i][j][nod].drmax = sp[j][st] - sp[i - 1][st];
arb[i][j][nod].smax = sp[j][st] - sp[i - 1][st];
return;
}
int mij = (st + dr) / 2;
prop(i, j, nod * 2, st, mij);
prop(i, j, nod * 2 + 1, mij + 1, dr);
arb[i][j][nod].sp = arb[i][j][nod * 2].sp + arb[i][j][nod * 2 + 1].sp;
arb[i][j][nod].stmax = max(arb[i][j][nod * 2].stmax, arb[i][j][nod * 2].sp + arb[i][j][nod * 2 + 1].stmax);
arb[i][j][nod].drmax = max(arb[i][j][nod * 2 + 1].drmax, arb[i][j][nod * 2].drmax + arb[i][j][nod * 2 + 1].sp);
arb[i][j][nod].smax = max(max(arb[i][j][nod * 2].smax, arb[i][j][nod * 2 + 1].smax), arb[i][j][nod * 2].drmax + arb[i][j][nod * 2 + 1].stmax);
}
void update(int i, int j, int nod, int st, int dr, int val, int pos) {
if (st == dr) {
arb[i][j][nod].sp += val;
arb[i][j][nod].stmax += val;
arb[i][j][nod].drmax += val;
arb[i][j][nod].smax += val;
return;
}
int mij = (st + dr) / 2;
if (pos <= mij) {
update(i, j, nod * 2, st, mij, val, pos);
} else {
update(i, j, nod * 2 + 1, mij + 1, dr, val, pos);
}
arb[i][j][nod].sp = arb[i][j][nod * 2].sp + arb[i][j][nod * 2 + 1].sp;
arb[i][j][nod].stmax = max(arb[i][j][nod * 2].stmax, arb[i][j][nod * 2].sp + arb[i][j][nod * 2 + 1].stmax);
arb[i][j][nod].drmax = max(arb[i][j][nod * 2 + 1].drmax, arb[i][j][nod * 2].drmax + arb[i][j][nod * 2 + 1].sp);
arb[i][j][nod].smax = max(max(arb[i][j][nod * 2].smax, arb[i][j][nod * 2 + 1].smax), arb[i][j][nod * 2].drmax + arb[i][j][nod * 2 + 1].stmax);
}
NOD query(int i, int j, int nod, int st, int dr, int MIN, int MAX) {
// cerr << st << " " << dr << '\n';
if (MIN <= st && dr <= MAX) {
return arb[i][j][nod];
}
int mij = (st + dr) / 2;
if (MAX <= mij) {
return query(i, j, nod * 2, st, mij, MIN, MAX);
}
if (MIN > mij) {
return query(i, j, nod * 2 + 1, mij + 1, dr, MIN, MAX);
}
NOD left = query(i, j, nod * 2, st, mij, MIN, MAX);
NOD right = query(i, j, nod * 2 + 1, mij + 1, dr, MIN, MAX);
NOD now;
now.sp = left.sp + right.sp;
now.stmax = max(left.stmax, left.sp + right.stmax);
now.drmax = max(right.drmax, right.sp + left.drmax);
now.smax = max(max(left.smax, right.smax), left.drmax + right.stmax);
return now;
}
void solve() {
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
arb[i][j].resize(4 * m + 5);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sp[i][j] = sp[i - 1][j] + v[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
prop(i, j, 1, 1, m);
}
}
for (int t = 1; t <= q; t++) {
if (qr[t].tip == 1) {
for (int i = 1; i <= qr[t].x; i++) {
for (int j = qr[t].x; j <= n; j++) {
update(i, j, 1, 1, m, qr[t].val - v[qr[t].x][qr[t].y], qr[t].y);
}
}
v[qr[t].x][qr[t].y] = qr[t].val;
}
if (qr[t].tip == 2) {
long long ans = -1e18;
for (int i = qr[t].x1; i <= qr[t].x2; i++) {
for (int j = i; j <= qr[t].x2; j++) {
// cerr << qr[t].y1 << " " << qr[t].y2 << " " << '\n';
NOD now = query(i, j, 1, 1, m, qr[t].y1, qr[t].y2);
ans = max(ans, now.smax);
}
}
cout << ans << '\n';
}
}
}
void brut3() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sp[i][j] = sp[i - 1][j] + v[i][j];
}
}
for (int t = 1; t <= q; t++) {
if (qr[t].tip == 1) {
v[qr[t].x][qr[t].y] = qr[t].val;
for (int i = 1; i <= n; i++) {
sp[i][qr[t].y] = sp[i - 1][qr[t].y] + v[i][qr[t].y];
}
}
if (qr[t].tip == 2) {
long long ans = -1e18;
for (int i = qr[t].x1; i <= qr[t].x2; i++) {
for (int j = i; j <= qr[t].x2; j++) {
long long now = 0, MIN = 0;
for (int k = qr[t].y1; k <= qr[t].y2; k++) {
now += sp[j][k] - sp[i - 1][k];
ans = max(ans, now - MIN);
MIN = min(MIN, now);
}
}
}
cout << ans << '\n';
}
}
}
void brut4() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sp[i][j] = sp[i - 1][j] + v[i][j];
}
}
for (int t = 1; t <= q; t++) {
if (qr[t].tip == 1) {
v[qr[t].x][qr[t].y] = qr[t].val;
for (int i = 1; i <= n; i++) {
sp[i][qr[t].y] = sp[i - 1][qr[t].y] + v[i][qr[t].y];
}
}
if (qr[t].tip == 2) {
long long ans = -1e18;
for (int i = qr[t].x1; i <= qr[t].x2; i++) {
for (int I = i; I <= qr[t].x2; I++) {
for (int j = qr[t].y1; j <= qr[t].y2; j++) {
long long now = 0;
for (int J = j; J <= qr[t].y2; J++) {
now += sp[I][J] - sp[i - 1][J];
ans = max(ans, now);
}
}
}
}
cout << ans << '\n';
}
}
}
int main() {
// freopen("input", "r", stdin);freopen("output", "w", stdout);
read();
solve();
return 0;
}