mirror of
https://git.sb/baoshuo/OI-codes.git
synced 2024-12-26 21:52:00 +00:00
244 lines
6.9 KiB (Stored with Git LFS)
C++
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;
|
|
}
|