제출 #829041

#제출 시각아이디문제언어결과실행 시간메모리
829041PurpleCrayonRectangles (IOI19_rect)C++17
컴파일 에러
0 ms0 KiB
#include "rect.h"
#include <bits/stdc++.h>
using namespace std;

#define sz(v) int(v.size())
#define ar array
typedef long long ll;
const int N = 2.5e3+10;

int n, m, prv_u[N][N], prv_d[N][N], prv_l[N][N], prv_r[N][N];
vector<int> sorted[N];
vector<short> ups[N][N], rights[N][N];
vector<short> can_ups[N][N], can_rights[N][N];
int far[N];

long long count_rectangles(const vector<vector<int>>& a) {
	n = sz(a), m = sz(a[0]);

	memset(prv_u, -1, sizeof(prv_u));
	memset(prv_d, -1, sizeof(prv_d));
	memset(prv_l, -1, sizeof(prv_l));
	memset(prv_r, -1, sizeof(prv_r));
	for (int i = 0; i < n; i++) {
		vector<int> stk;
		for (int j = 0; j < m; j++) {
			while (sz(stk) && a[stk.back() / m][stk.back() % m] <= a[i][j]) stk.pop_back();
			if (sz(stk)) prv_l[i][j] = stk.back();
			stk.push_back(i * m + j);
		}
	}

	for (int i = 0; i < n; i++) {
		vector<int> stk;
		for (int j = m-1; j >= 0; j--) {
			while (sz(stk) && a[stk.back() / m][stk.back() % m] < a[i][j]) stk.pop_back();
			if (sz(stk)) prv_r[i][j] = stk.back();
			stk.push_back(i * m + j);
		}
	}

	for (int j = 0; j < m; j++) {
		vector<int> stk;
		for (int i = 0; i < n; i++) {
			while (sz(stk) && a[stk.back() / m][stk.back() % m] <= a[i][j]) stk.pop_back();
			if (sz(stk)) prv_u[i][j] = stk.back();
			stk.push_back(i * m + j);
		}
	}

	for (int j = 0; j < m; j++) {
		vector<int> stk;
		for (int i = n-1; i >= 0; i--) {
			while (sz(stk) && a[stk.back() / m][stk.back() % m] < a[i][j]) stk.pop_back();
			if (sz(stk)) prv_d[i][j] = stk.back();
			stk.push_back(i * m + j);
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (prv_d[i][j] == -1 || a[prv_d[i][j] / m][prv_d[i][j] % m] <= a[i][j]) continue;
			if (prv_u[i][j] == -1 || a[prv_u[i][j] / m][prv_u[i][j] % m] <= a[i][j]) continue;
			sorted[prv_u[i][j] / m].push_back(prv_d[i][j]);
			// ups[prv_d[i][j] / m][prv_d[i][j] % m].push_back(prv_u[i][j] / m);
		}
	}

	for (int i = 0; i < n; i++) {
		for (int c : sorted[i]) {
			ups[c / m][c % m].push_back(i);
		}
		vector<int>().swap(sorted[i]);
	}


	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (prv_l[i][j] == -1 || a[prv_l[i][j] / m][prv_l[i][j] % m] <= a[i][j]) continue;
			if (prv_r[i][j] == -1 || a[prv_r[i][j] / m][prv_r[i][j] % m] <= a[i][j]) continue;
			sorted[prv_r[i][j] % m].push_back(prv_l[i][j]);
			// rights[prv_l[i][j] / m][prv_l[i][j] % m].push_back(prv_r[i][j] % m);
		}
	}

	for (int i = 0; i < m; i++) {
		for (int c : sorted[i]) {
			rights[c / m][c % m].push_back(i);
		}

		vector<int>().swap(sorted[i]);
	}

	for (int i = 0; i < n; i++) {
		memset(far, -1, sizeof(far));
		for (int j = m-1; j >= 0; j--) {
			int k = sz(ups[i][j]);
			can_ups[i][j].resize(k);

			for (int c = 0; c < k; c++) {
				can_ups[i][j][c] = far[ups[i][j][c]] != -1 ? far[ups[i][j][c]] : j;
			}

			if (j < m-1) {
				for (int c = 0; c < sz(ups[i][j+1]); c++)
					far[ups[i][j+1][c]] = -1;
			}

			for (int c = 0; c < k; c++)
				far[ups[i][j][c]] = can_ups[i][j][c];
		}
	}

	for (int j = 0; j < m; j++) {
		memset(far, -1, sizeof(far));
		for (int i = 0; i < n; i++) {
			int k = sz(rights[i][j]);
			can_rights[i][j].resize(k);

			for (int c = 0; c < k; c++) {
				can_rights[i][j][c] = far[rights[i][j][c]] != -1 ? far[rights[i][j][c]] : i;
			}

			if (i > 0) {
				for (int c = 0; c < sz(rights[i-1][j]); c++)
					far[rights[i-1][j][c]] = -1;
			}

			for (int c = 0; c < k; c++)
				far[rights[i][j][c]] = can_rights[i][j][c];
		}
	}

	// for (int i = 0; i < n; i++) {
	// 	for (int j = 0; j < m; j++) {
	// 		if (sz(ups[i][j])) {
	// 			cerr << "ups: " << 	i << ' ' << j << endl;
	// 			for (int c : ups[i][j]) cerr << c << ' ';
	// 			cerr << endl;
	// 		}
	// 	}
	// }

	// for (int i = 0; i < n; i++) {
	// 	for (int j = 0; j < m; j++) {
	// 		if (sz(rights[i][j])) {
	// 			cerr << "rights: " << i << ' ' << j << endl;
	// 			for (int c : rights[i][j]) cerr << c << ' ';
	// 			cerr << endl;
	// 		}
	// 	}
	// }

	ll ans = 0;
	for (int i = 1; i < n; i++) {
		for (int j = 0; j < m-1; j++) {
			int k1 = sz(ups[i][j+1]);
			int k2 = sz(rights[i-1][j]);
			for (int a = 0; a < k1; a++) {
				for (int b = 0; b < k2; b++) {
					// if (i == 2 && j == 2 && ups[i][j+1][a] == 0 && rights[i-1][j][b] == 4) {
					// 	cerr << "HERE: " << can_rights[i-1][j][b] << ' ' << can_ups[i][j+1][a] << endl;
					// }

					if (rights[i-1][j][b] > can_ups[i][j+1][a] + 1) break;
					if (ups[i][j+1][a] >= can_rights[i-1][j][b] - 1) {
						// cout << ups[i][j+1][a] << ' ' << i << ' ' << j << ' ' << rights[i-1][j][b] << endl;
						ans++;
					}
				}
			}
		}
	}

	return ans;
}

컴파일 시 표준 에러 (stderr) 메시지

/usr/bin/ld: /tmp/ccbATQeT.o: in function `main':
grader.cpp:(.text.startup+0x6fa): undefined reference to `count_rectangles(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >)'
collect2: error: ld returned 1 exit status