Submission #727285

# Submission time Handle Problem Language Result Execution time Memory
727285 2023-04-20T11:11:22 Z SanguineChameleon Hexagonal Territory (APIO21_hexagon) C++17
20 / 100
709 ms 67904 KB
#include "hexagon.h"
#include <bits/stdc++.h>
using namespace std;

#ifdef KAMIRULEZ
	const bool local = true;
	const int subtask = 8;
#else
	const bool local = false;
	const int subtask = -1;
#endif

const long long mod = 1e9 + 7;
const long long one_half = (mod + 1) / 2;
const long long one_third = (mod + 1) / 3;
const int dx[7] = {0, 0, 1, 1, 0, -1, -1};
const int dy[7] = {0, 1, 1, 0, -1, -1, 0};

struct point {
	long long x, y;

	point() {};

	point(long long _x, long long _y): x(_x), y(_y) {};

	point operator*(long long d) {
		return point(x * d, y * d);
	}

	point operator+(point p2) {
		return point(x + p2.x, y + p2.y);
	}

	long long operator^(point p2) {
		return x * p2.y - y * p2.x;
	}
};

point dv[7] = {point(0, 0), point(0, 1), point(1, 1), point(1, 0), point(0, -1), point(-1, -1), point(-1, 0)};

ostream& operator<<(ostream &out, point p) {
	out << "(" << p.x << "," << p.y << ")";
	return out;
}

struct line {
	int type, dir, len, id;
	point p1, p2;

	line() {};

	line(int _type): type(_type) {};

	line(int _type, int _dir, point _p1, point _p2, int _id): type(_type), dir(_dir), p1(_p1), p2(_p2), id(_id) {
		len = p2.x - p1.x + 1;
	};

	long long calc() {
		long long res = 0;
		long long Ly = p1.y;
		long long Ry = p1.y + (dir == 1 ? 0 : len - 1);
		if (type == 1) {
			Ly = 1 - Ly;
			Ry = 1 - Ry;
		}
		return (Ly + Ry) % mod * len % mod * one_half % mod;
	}

	long long eval_x(long long x) {
		if (dir == 1) {
			return p1.y;
		}
		else {
			return p1.y + (x - p1.x);
		}
	}
};

ostream& operator<<(ostream &out, line L) {
	if (L.type == 1) {
		out << "(bottom,";
	}
	else {
		out << "(top,";
	}
	out << L.p1 << "," << L.p2 << ")";
	return out;
}

bool operator<(line L1, line L2) {
	if (L1.type == -1) {
		return true;
	}
	int max_x = max(L1.p1.x, L2.p1.x);
	int v1 = L1.eval_x(max_x);
	int v2 = L2.eval_x(max_x);
	if (v1 != v2) {
		return v1 < v2;
	}
	else {
		return L1.type < L2.type;
	}
};

int draw_territory(int N, int A, int B, vector<int> D, vector<int> L) {
	if (N == 3 && (!local || subtask == 1 || subtask == 2)) {
		int len = L[0] + 1;
		long long A_sum = 1LL * len * (len + 1) % mod * one_half % mod;
		long long B_sum = 1LL * len * (len - 1) % mod * one_half % mod + (len - 1) * len % mod * (len * 2 - 1) % mod * one_half % mod * one_third % mod;
		return (A_sum * A + B_sum * B) % mod;
	}
	long long L_sum = 0;
	for (int i = 0; i < N; i++) {
		L_sum += L[i];
	}
	if (L_sum <= 2000 && (!local || subtask == 3)) {
		vector<vector<bool>> border(4069, vector<bool>(4069, false));
		vector<vector<int>> dist(4069, vector<int>(4069, -1));
		int cx = 0;
		int cy = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < L[i]; j++) {
				cx += dx[D[i]];
				cy += dy[D[i]];
				border[cx + 2023][cy + 2023] = true;
			}
		}
		deque<pair<int, int>> q = {{0, 0}};
		dist[0][0] = -2;
		while (!q.empty()) {
			cx = q.front().first;
			cy = q.front().second;
			q.pop_front();
			for (int d = 1; d <= 6; d++) {
				int nx = cx + dx[d];
				int ny = cy + dy[d];
				if (0 <= nx && nx < 4069 && 0 <= ny && ny < 4069 && !border[nx][ny] && dist[nx][ny] == -1) {
					dist[nx][ny] = -2;
					q.push_back({nx, ny});
				}
			}
		}
		q.push_back({2023, 2023});
		dist[2023][2023] = 0;
		long long res = 0;
		while (!q.empty()) {
			cx = q.front().first;
			cy = q.front().second;
			res += 1LL * B * dist[cx][cy] + A;
			res %= mod;
			q.pop_front();
			for (int d = 1; d <= 6; d++) {
				int nx = cx + dx[d];
				int ny = cy + dy[d];
				if (0 <= nx && nx < 4069 && 0 <= ny && ny < 4069 && dist[nx][ny] == -1) {
					dist[nx][ny] = dist[cx][cy] + 1;
					q.push_back({nx, ny});
				}
			}
		}
		return res;
	}
	long long area = 0;
	point cur = point(0, 0);
	vector<point> poly(N);
	for (int i = 0; i < N; i++) {
		poly[i] = cur;
		cur = cur + (dv[D[i]] * L[i]);
	}
	for (int i = 0; i < N; i++) {
		area += poly[i] ^ poly[(i + 1) % N];
	}
	if (area < 0) {
		reverse(D.begin(), D.end());
		for (int i = 0; i < N; i++) {
			if (D[i] <= 3) {
				D[i] += 3;
			}
			else {
				D[i] -= 3;
			}
		}
		reverse(L.begin(), L.end());
		cur = point(0, 0);
		for (int i = 0; i < N; i++) {
			poly[i] = cur;
			cur = cur + (dv[D[i]] * L[i]);
		}
	}
	vector<line> lines;
	for (int i = 0; i < N; i++) {
		point prv = poly[(i + (N - 1)) % N];
		point cur = poly[i];
		point nxt1 = poly[(i + 1) % N];
		point nxt2 = poly[(i + 2) % N];
		if (cur.x < nxt1.x) {
			point p1 = cur;
			point p2 = nxt1;
			int dir = (cur.y == nxt1.y ? 1 : 2);
			if (prv.x < cur.x) {
				if (dir == 1) {
					p1 = p1 + point(1, 0);
				}
				else {
					p1 = p1 + point(1, 1);
				}
			}
			if (prv.x == cur.x && prv.y < cur.y) {
				if (dir == 1) {
					p1 = p1 + point(1, 0);
				}
				else {
					p1 = p1 + point(1, 1);
				}
			}
			if (nxt1.x == nxt2.x && nxt1.y > nxt2.y) {
				if (dir == 1) {
					p2 = p2 + point(-1, 0);
				}
				else {
					p2 = p2 + point(-1, -1);
				}
			}
			if (p1.x <= p2.x) {
				lines.emplace_back(1, dir, p1, p2, lines.size());
			}
		}
		if (cur.x > nxt1.x) {
			point p1 = nxt1;
			point p2 = cur;
			int dir = (cur.y == nxt1.y ? 1 : 2);
			if (prv.x > cur.x) {
				if (dir == 1) {
					p2 = p2 + point(-1, 0);
				}
				else {
					p2 = p2 + point(-1, -1);
				}
			}
			if (prv.x == cur.x && prv.y > cur.y) {
				if (dir == 1) {
					p2 = p2 + point(-1, 0);
				}
				else {
					p2 = p2 + point(-1, -1);
				}
			}
			if (nxt1.x == nxt2.x && nxt1.y < nxt2.y) {
				if (dir == 1) {
					p1 = p1 + point(1, 0);
				}
				else {
					p1 = p1 + point(1, 1);
				}
			}
			if (p1.x <= p2.x) {
				lines.emplace_back(2, dir, p1, p2, lines.size());
			}
		}
	}
	if (B == 0 && (!local || subtask == 4 || subtask == 5)) {
		long long res = 0;
		for (auto L: lines) {
			cout << L << '\n';
			res += L.calc();
			res %= mod;
		}
		if (res < 0) {
			res += mod;
		}
		res = res * A % mod;
		return res;
	}
/*	vector<pair<int, pair<int, line>>> events;
	for (auto L: lines) {
		events.push_back({L.p1.x, {0, L}});
		events.push_back({L.p2.x, {1, L}});
	}
	sort(events.begin(), events.end());
	set<line, less<>> S;
	line prv_top(-1);
	for (auto e: events) {
		int cur_x = e.first;
		int type = e.second.first;
		line L = e.second.second;
		if (type == 0) {
			prv_top = line(-1);
			S.insert(L);
		}
		else {
			auto it = S.lower_bound(L);
			if (it->type == 1 && next(it) != S.end() && next(it)->type == 2 && next(it)->p2.x > cur_x && prv_top < *it)  {
				cout << "match" << " " << (*it) << " " << (*next(it)) << " " << cur_x << '\n';
				cout << '\n';
				prv_top = *next(it);
			}
			if (it->type == 2 && it != S.begin() && prev(it)->type == 1 && prv_top < *prev(it))  {
				cout << "match" << " " << (*prev(it)) << " " << (*it) << " " << cur_x << '\n';
				cout << '\n';
				prv_top = *it;
			}
			S.erase(it);
		}
		for (auto L: S) {
			cout << L << '\n';
		}
		cout << '\n';
	}*/
	return 0;
}

Compilation message

hexagon.cpp: In constructor 'line::line(int, int, point, point, int)':
hexagon.cpp:48:12: warning: 'line::p2' will be initialized after [-Wreorder]
   48 |  point p1, p2;
      |            ^~
hexagon.cpp:47:22: warning:   'int line::id' [-Wreorder]
   47 |  int type, dir, len, id;
      |                      ^~
hexagon.cpp:54:2: warning:   when initialized here [-Wreorder]
   54 |  line(int _type, int _dir, point _p1, point _p2, int _id): type(_type), dir(_dir), p1(_p1), p2(_p2), id(_id) {
      |  ^~~~
hexagon.cpp: In member function 'long long int line::calc()':
hexagon.cpp:59:13: warning: unused variable 'res' [-Wunused-variable]
   59 |   long long res = 0;
      |             ^~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 304 KB Output is correct
3 Correct 1 ms 300 KB Output is correct
4 Correct 1 ms 296 KB Output is correct
5 Correct 1 ms 304 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 304 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 300 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 1 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 1 ms 212 KB Output is correct
8 Correct 1 ms 212 KB Output is correct
9 Correct 1 ms 212 KB Output is correct
10 Correct 1 ms 300 KB Output is correct
11 Correct 1 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 663 ms 67548 KB Output is correct
2 Correct 645 ms 67796 KB Output is correct
3 Correct 647 ms 67532 KB Output is correct
4 Correct 646 ms 67668 KB Output is correct
5 Correct 647 ms 67532 KB Output is correct
6 Correct 620 ms 67680 KB Output is correct
7 Correct 624 ms 67520 KB Output is correct
8 Correct 648 ms 67520 KB Output is correct
9 Correct 647 ms 67672 KB Output is correct
10 Correct 620 ms 67784 KB Output is correct
11 Correct 640 ms 67564 KB Output is correct
12 Correct 641 ms 67684 KB Output is correct
13 Correct 684 ms 67660 KB Output is correct
14 Correct 704 ms 67552 KB Output is correct
15 Correct 693 ms 67596 KB Output is correct
16 Correct 631 ms 67684 KB Output is correct
17 Correct 626 ms 67548 KB Output is correct
18 Correct 1 ms 212 KB Output is correct
19 Correct 1 ms 212 KB Output is correct
20 Correct 1 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 212 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 296 KB Output is correct
3 Incorrect 1 ms 212 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 709 ms 67548 KB Output is correct
2 Correct 632 ms 67532 KB Output is correct
3 Correct 634 ms 67792 KB Output is correct
4 Correct 647 ms 67752 KB Output is correct
5 Correct 638 ms 67812 KB Output is correct
6 Correct 651 ms 67572 KB Output is correct
7 Correct 637 ms 67668 KB Output is correct
8 Correct 630 ms 67796 KB Output is correct
9 Correct 639 ms 67468 KB Output is correct
10 Correct 643 ms 67676 KB Output is correct
11 Correct 633 ms 67672 KB Output is correct
12 Correct 635 ms 67680 KB Output is correct
13 Correct 633 ms 67616 KB Output is correct
14 Correct 649 ms 67572 KB Output is correct
15 Correct 642 ms 67684 KB Output is correct
16 Correct 642 ms 67780 KB Output is correct
17 Correct 703 ms 67764 KB Output is correct
18 Incorrect 1 ms 212 KB Output isn't correct
19 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Incorrect 1 ms 212 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 624 ms 67552 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 1 ms 296 KB Output is correct
4 Correct 1 ms 300 KB Output is correct
5 Correct 1 ms 296 KB Output is correct
6 Correct 638 ms 67904 KB Output is correct
7 Correct 644 ms 67644 KB Output is correct
8 Correct 642 ms 67808 KB Output is correct
9 Correct 656 ms 67648 KB Output is correct
10 Correct 641 ms 67604 KB Output is correct
11 Correct 643 ms 67780 KB Output is correct
12 Correct 634 ms 67664 KB Output is correct
13 Correct 636 ms 67568 KB Output is correct
14 Correct 642 ms 67684 KB Output is correct
15 Correct 651 ms 67648 KB Output is correct
16 Correct 639 ms 67692 KB Output is correct
17 Correct 639 ms 67692 KB Output is correct
18 Correct 641 ms 67780 KB Output is correct
19 Correct 633 ms 67568 KB Output is correct
20 Correct 645 ms 67776 KB Output is correct
21 Correct 658 ms 67656 KB Output is correct
22 Incorrect 1 ms 212 KB Output isn't correct
23 Halted 0 ms 0 KB -