Submission #727233

#TimeUsernameProblemLanguageResultExecution timeMemory
727233SanguineChameleonHexagonal Territory (APIO21_hexagon)C++17
47 / 100
695 ms67812 KiB
#include "hexagon.h" #include <bits/stdc++.h> using namespace std; #ifdef KAMIRULEZ const bool local = true; const int subtask = 5; #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; point p1, p2; line() {}; line(int _type, int _dir, point _p1, point _p2): type(_type), dir(_dir), p1(_p1), p2(_p2) { 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; } }; ostream& operator<<(ostream &out, line L) { if (L.type == 1) { out << "bottom line, "; } else { out << "top line, "; } if (L.dir == 1) { out << "straight, "; } else { out << "diagonal, "; } out << "from" << " " << L.p1 << " to " << L.p2; return out; } 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); } } 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); } } } if (B == 0 && (!local || subtask == 4 || subtask == 5)) { long long res = 0; for (auto L: lines) { res += L.calc(); res %= mod; } if (res < 0) { res += mod; } res = res * A % mod; return res; } return 0; }

Compilation message (stderr)

hexagon.cpp: In member function 'long long int line::calc()':
hexagon.cpp:57:13: warning: unused variable 'res' [-Wunused-variable]
   57 |   long long res = 0;
      |             ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...