Submission #523419

#TimeUsernameProblemLanguageResultExecution timeMemory
523419boykutUFO (IZhO14_ufo)C++14
50 / 100
2086 ms77728 KiB
#include <bits/stdc++.h>

using namespace std;

vector<vector<int>> a;
vector<vector<long long>> pref;

struct segment_tree {
	int n;
	vector<int> t;
	segment_tree() {
	}
	segment_tree(size_t s) {
		n = 1;
		while (n < s) n <<= 1;
		t.assign(2 * n, 0);
	}
	void update(int i, int x, int v, int vl, int vr) {
		if (vl == vr) {
			t[v] += x;
		} else {
			int vm = vl + vr >> 1;
			if (i <= vm)
				update(i, x, v << 1, vl, vm);
			else
				update(i, x, v << 1 | 1, vm + 1, vr);
			t[v] = max(t[v << 1], t[v << 1 | 1]);
		}
	}
	void update(int i, int x) {
		update(i, x, 1, 0, n - 1);
	}
	int query(int l, int r, int v, int vl, int vr) {
		if (l > vr || vl > r) return INT_MIN;
		if (l <= vl && vr <= r) return t[v];
		int vm = vl + vr >> 1;
		int q1 = query(l, r, v << 1, vl, vm);
		int q2 = query(l, r, v << 1 | 1, vm + 1, vr);
		return max(q1, q2);
	}
	int query(int l, int r) {
		return query(l, r, 1, 0, n - 1);
	}
};

vector<segment_tree> row, col;

int getmaxRow(int x, int l, int r) {
	//int ans = INT_MIN;
	//for (int j = l; j <= r; j++) ans = max(ans, a[x][j]);
	return row[x].query(l, r);
};

int getmaxCol(int x, int l, int r) {
	// int ans = INT_MIN;
	// for (int j = l; j <= r; j++) ans = max(ans, a[j][x]);
	return col[x].query(l, r);
};

void updateRow(int x, int j) {
	//a[x][j]--;
	row[x].update(j, -1);
	col[j].update(x, -1);
}
void updateCol(int x, int j) {
	//a[j][x]--;
	col[x].update(j, -1);
	row[j].update(x, -1);
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n, m, r, k, p;
	cin >> n >> m >> r >> k >> p;

	a = vector<vector<int>>(n, vector<int>(m));
	row = vector<segment_tree> (n);
	col = vector<segment_tree> (m);

	for (int i = 0; i < n; i++) {
		row[i] = segment_tree(m);
		for (int j = 0; j < m; j++) {
			cin >> a[i][j];
			row[i].update(j, a[i][j]);
		}
	}
	for (int j = 0; j < m; j++) {
		col[j] = segment_tree(n);
		for (int i = 0; i < n; i++) {
			col[j].update(i, a[i][j]);
		}
	}

	while (k--) {
		char c; cin >> c;
		int x, y; cin >> x >> y;
		int cnt = r;
		x--;		

		if (c == 'W') {
			int start = 0;
			while (cnt > 0 && start < m) {
				int l = start, r = m - 1;
				while (l < r) {
					int m = (l + r) / 2;
					if (getmaxRow(x, start, m) >= y)
						r = m;
					else
						l = m + 1;
				}
				if (getmaxRow(x, start, r) >= y) {
					updateRow(x, r);
					cnt--;
					start = r + 1;
				} else break;
			}
		} else if (c == 'E') {
			int start = m - 1;
			while (cnt > 0 && start >= 0) {
				int l = 0, r = start;
				while (l < r) {
					int m = (l + r + 1) / 2;
					if (getmaxRow(x, m, start) >= y)
						l = m;
					else
						r = m - 1;
				}
				if (getmaxRow(x, l, start) >= y) {
					updateRow(x, l);
					cnt--;
					start = l - 1;
				} else break;
			}
		} else if (c == 'N') {
			int start = 0;
			while (cnt > 0 && start < n) {
				int l = start, r = n - 1;
				while (l < r) {
					int m = (l + r) / 2;
					if (getmaxCol(x, start, m) >= y)
						r = m;
					else
						l = m + 1;
				}
				if (getmaxCol(x, start, r) >= y) {
					updateCol(x, r);
					cnt--;
					start = r + 1;
				} else break;
			}
		} else {
			int start = n - 1;
			while (cnt > 0 && start >= 0) {
				int l = 0, r = start;
				while (l < r) {
					int m = (l + r + 1) / 2;
					if (getmaxCol(x, m, start) >= y)
						l = m;
					else
						r = m - 1;
				}
				if (getmaxCol(x, l, start) >= y) {
					updateCol(x, l);
					cnt--;
					start = l - 1;
				} else break;
			}
		}
	}

	//cout << row[0].query(0, m-1) << '\n';

	pref = vector<vector<long long>>(n, vector<long long>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			a[i][j] = row[i].query(j, j);
			//cout << a[i][j] << ' ';
			pref[i][j] = a[i][j];
			pref[i][j] += (i ? pref[i-1][j] : 0);
			pref[i][j] += (j ? pref[i][j-1] : 0);
			pref[i][j] -= (i && j ? pref[i-1][j-1] : 0);
		}
		cout << '\n';
	}

	auto get = [&](int a, int b, int c, int d) ->long long {
		long long s = pref[c][d];
		s -= (a ? pref[a-1][d] : 0);
		s -= (b ? pref[c][b-1] : 0);
		s += (a && b ? pref[a-1][b-1] : 0);
		return s;
	};

	long long ans = LLONG_MIN;
	for (int i = 0; i + p - 1 < n; i++) {
		for (int j = 0; j + p - 1 < m; j++) {
			ans = max(ans, get(i, j, i + p - 1, j + p - 1));
		}
	}
	cout << ans << '\n';

	return 0;
}

Compilation message (stderr)

ufo.cpp: In constructor 'segment_tree::segment_tree(size_t)':
ufo.cpp:15:12: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
   15 |   while (n < s) n <<= 1;
      |          ~~^~~
ufo.cpp: In member function 'void segment_tree::update(int, int, int, int, int)':
ufo.cpp:22:16: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   22 |    int vm = vl + vr >> 1;
      |             ~~~^~~~
ufo.cpp: In member function 'int segment_tree::query(int, int, int, int, int)':
ufo.cpp:36:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   36 |   int vm = vl + vr >> 1;
      |            ~~~^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...