답안 #328607

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
328607 2020-11-17T10:45:59 Z dolphingarlic Nafta (COI15_nafta) C++14
100 / 100
532 ms 121192 KB
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

int n, m;
char grid[2001][2001];
bool visited[2001][2001];
int dx[4]{1, -1, 0, 0}, dy[4]{0, 0, 1, -1};
int bit[2001], diff[2001][2001], dp[2001][2001];

bool inside(int x, int y) {
	return x && y && x <= n && y <= m && !visited[x][y] && grid[x][y] != '.';
}

tuple<int, int, int> get_oil(int x, int y) {
	tuple<int, int, int> ret = {y, y, grid[x][y] - '0'};
	visited[x][y] = true;
	for (int i = 0; i < 4; i++) if (inside(x + dx[i], y + dy[i])) {
		tuple<int, int, int> pot = get_oil(x + dx[i], y + dy[i]);
		get<0>(ret) = min(get<0>(ret), get<0>(pot));
		get<1>(ret) = max(get<1>(ret), get<1>(pot));
		get<2>(ret) += get<2>(pot);
	}
	return ret;
}

void update(int pos, int val) { for (; pos <= m; pos += pos & -pos) bit[pos] += val; }

int query(int pos) {
	int ans = 0;
	for (; pos; pos -= pos & -pos) ans += bit[pos];
	return ans;
}

void solve(int placed, int l = 1, int r = m, int opt_l = 0, int opt_r = m - 1) {
	int mid = (l + r) / 2;
	int opt = -1;
	for (int i = opt_l; i <= min(mid - 1, opt_r); i++) {
		if (dp[placed - 1][i] + diff[mid][i] > dp[placed][mid]) {
			dp[placed][mid] = dp[placed - 1][i] + diff[mid][i];
			opt = i;
		}
	}
	if (l != r) {
		solve(placed, l, mid, opt_l, opt);
		solve(placed, mid + 1, r, opt, opt_r);
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) {
		cin >> grid[i][j];
	}
	vector<tuple<int, int, int>> oil;
	for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) {
		if (inside(i, j)) {
			int l, r, val;
			tie(l, r, val) = get_oil(i, j);
			oil.push_back({l, l, val});
			oil.push_back({r + 1, l, -val});
		}
	}
	sort(oil.begin(), oil.end());
	for (int i = 1, ptr = 0; i <= m; i++) {
		while (get<0>(oil[ptr]) <= i) {
			update(get<1>(oil[ptr]), get<2>(oil[ptr]));
			ptr++;
		}
		for (int j = 0; j < i; j++) diff[i][j] = query(i) - query(j);
	}
	for (int i = 1; i <= m; i++) {
		solve(i);
		cout << *max_element(dp[i] + 1, dp[i] + m + 1) << '\n';
	}
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1132 KB Output is correct
2 Correct 1 ms 1004 KB Output is correct
3 Correct 1 ms 1004 KB Output is correct
4 Correct 1 ms 1004 KB Output is correct
5 Correct 1 ms 1004 KB Output is correct
6 Correct 2 ms 1004 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1132 KB Output is correct
2 Correct 1 ms 1004 KB Output is correct
3 Correct 1 ms 1004 KB Output is correct
4 Correct 1 ms 1004 KB Output is correct
5 Correct 1 ms 1004 KB Output is correct
6 Correct 2 ms 1004 KB Output is correct
7 Correct 15 ms 4840 KB Output is correct
8 Correct 11 ms 4780 KB Output is correct
9 Correct 12 ms 6508 KB Output is correct
10 Correct 10 ms 4780 KB Output is correct
11 Correct 9 ms 4588 KB Output is correct
12 Correct 8 ms 4588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1132 KB Output is correct
2 Correct 1 ms 1004 KB Output is correct
3 Correct 1 ms 1004 KB Output is correct
4 Correct 1 ms 1004 KB Output is correct
5 Correct 1 ms 1004 KB Output is correct
6 Correct 2 ms 1004 KB Output is correct
7 Correct 15 ms 4840 KB Output is correct
8 Correct 11 ms 4780 KB Output is correct
9 Correct 12 ms 6508 KB Output is correct
10 Correct 10 ms 4780 KB Output is correct
11 Correct 9 ms 4588 KB Output is correct
12 Correct 8 ms 4588 KB Output is correct
13 Correct 505 ms 49848 KB Output is correct
14 Correct 490 ms 44096 KB Output is correct
15 Correct 532 ms 121192 KB Output is correct
16 Correct 406 ms 43728 KB Output is correct
17 Correct 393 ms 38252 KB Output is correct
18 Correct 353 ms 37992 KB Output is correct