#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
enum DIRECTION {
UP,
RIGHT,
DOWN,
LEFT
};
int n;
struct ship {
int x, y, dir;
ship() {}
ship(int _x, int _y, int _dir) : x(_x), y(_y), dir(_dir) {}
} a[maxn];
namespace verticalCompression {
int c[maxn], n1 = 0;
void init() {
for (int i = 1; i <= n; i++) c[++n1] = a[i].x;
sort(c + 1, c + n1 + 1);
n1 = unique(c + 1, c + n1 + 1) - c - 1;
}
int get(int x) {
return lower_bound(c + 1, c + n1 + 1, x) - c;
}
}
namespace horizontalCompression {
int c[maxn], n1 = 0;
void init() {
for (int i = 1; i <= n; i++) c[++n1] = a[i].y;
sort(c + 1, c + n1 + 1);
n1 = unique(c + 1, c + n1 + 1) - c - 1;
}
int get(int y) {
return lower_bound(c + 1, c + n1 + 1, y) - c;
}
}
namespace mainDiagonalCompression {
int c[maxn], n1 = 0;
void init() {
for (int i = 1; i <= n; i++) c[++n1] = a[i].x-a[i].y;
sort(c + 1, c + n1 + 1);
n1 = unique(c + 1, c + n1 + 1) - c- 1;
}
int get(int xMinusY) {
return lower_bound(c + 1, c + n1 + 1, xMinusY) - c;
}
}
namespace gwynDiagonalCompression {
int c[maxn], n1 = 0;
void init() {
for (int i = 1; i <= n; i++) c[++n1] = a[i].x+a[i].y;
sort(c + 1, c + n1 + 1);
n1 = unique(c + 1, c + n1 + 1) - c - 1;
}
int get(int xPlusY) {
return lower_bound(c + 1, c + n1 + 1, xPlusY) - c;
}
}
struct node {
int pos, idx;
node() {}
node(int _pos, int _idx) : pos(_pos), idx(_idx) {}
bool operator < (const node &other) const {
if (pos != other.pos) return pos < other.pos;
}
};
struct tuplets {
int dis, idxOne, idxTwo;
tuplets() {}
tuplets(int _dis, int _idxOne, int _idxTwo) : dis(_dis), idxOne(_idxOne), idxTwo(_idxTwo) {
if (idxOne > idxTwo) swap(idxOne, idxTwo);
}
bool operator < (const tuplets &other) const {
if (dis != other.dis) return dis < other.dis;
if (idxOne != other.idxOne) return idxOne < other.idxOne;
return idxTwo < other.idxTwo;
}
};
int cl[maxn];
set<node> verticalUp[maxn], verticalDown[maxn],
horizontalLeft[maxn], horizontalRight[maxn],
mainDiagonalUp[maxn], mainDiagonalLeft[maxn], mainDiagonalRight[maxn], mainDiagonalDown[maxn],
gwynDiagonalUp[maxn], gwynDiagonalLeft[maxn], gwynDiagonalRight[maxn], gwynDiagonalDown[maxn];
set<tuplets> pq;
int manhattanDistance(int x, int y) {
return abs(a[x].x-a[y].x) + abs(a[x].y-a[y].y);
}
void init() {
for (int _ = 1; _ <= n; _++) {
switch (a[_].dir) {
case UP :
verticalUp[horizontalCompression::get(a[_].y)].insert(node(a[_].x, _));
mainDiagonalUp[mainDiagonalCompression::get(a[_].x-a[_].y)].insert(node(a[_].y, _));
gwynDiagonalUp[gwynDiagonalCompression::get(a[_].x+a[_].y)].insert(node(a[_].y, _));
break;
case DOWN :
verticalDown[horizontalCompression::get(a[_].y)].insert(node(a[_].x, _));
mainDiagonalDown[mainDiagonalCompression::get(a[_].x-a[_].y)].insert(node(a[_].y, _));
gwynDiagonalDown[gwynDiagonalCompression::get(a[_].x+a[_].y)].insert(node(a[_].y, _));
break;
case LEFT :
horizontalLeft[verticalCompression::get(a[_].x)].insert(node(a[_].y, _));
mainDiagonalLeft[mainDiagonalCompression::get(a[_].x-a[_].y)].insert(node(a[_].y, _));
gwynDiagonalLeft[gwynDiagonalCompression::get(a[_].x+a[_].y)].insert(node(a[_].y, _));
break;
case RIGHT :
horizontalRight[verticalCompression::get(a[_].x)].insert(node(a[_].y, _));
mainDiagonalRight[mainDiagonalCompression::get(a[_].x-a[_].y)].insert(node(a[_].y, _));
gwynDiagonalRight[gwynDiagonalCompression::get(a[_].x+a[_].y)].insert(node(a[_].y, _));
default :
break;
}
}
for (int _ = 1; _ <= verticalCompression::n1; _++) {
for (auto [pos, idx] : horizontalLeft[_]) {
auto it = horizontalRight[_].lower_bound(node(pos, INT_MAX));
if (it != horizontalRight[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (auto [pos, idx] : horizontalRight[_]) {
auto it = horizontalLeft[_].lower_bound(node(pos, INT_MAX));
if (it != horizontalLeft[_].end())
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (int _ = 1; _ <= horizontalCompression::n1; _++) {
for (auto [pos, idx] : verticalUp[_]) {
auto it = verticalDown[_].lower_bound(node(pos, INT_MAX));
if (it != verticalDown[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (auto [pos, idx] : verticalDown[_]) {
auto it = verticalUp[_].lower_bound(node(pos, INT_MAX));
if (it != verticalUp[_].end()) pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (int _ = 1; _ <= mainDiagonalCompression::n1; _++) {
for (auto [pos, idx] : mainDiagonalDown[_]) {
auto it = mainDiagonalLeft[_].lower_bound(node(pos, INT_MAX));
if (it != mainDiagonalLeft[_].end()) pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
for (auto [pos, idx] : mainDiagonalLeft[_]) {
auto it = mainDiagonalDown[_].lower_bound(node(pos, INT_MAX));
if (it != mainDiagonalDown[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (auto [pos, idx] : mainDiagonalRight[_]) {
auto it = mainDiagonalUp[_].lower_bound(node(pos, INT_MAX));
if (it != mainDiagonalUp[_].end()) pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
for (auto [pos, idx] : mainDiagonalUp[_]) {
auto it = mainDiagonalRight[_].lower_bound(node(pos, INT_MAX));
if (it != mainDiagonalRight[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
}
for (int _ = 1; _ <= gwynDiagonalCompression::n1; _++) {
for (auto [pos, idx] : gwynDiagonalUp[_]) {
auto it = gwynDiagonalLeft[_].lower_bound(node(pos, INT_MAX));
if (it != gwynDiagonalLeft[_].end()) pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
for (auto [pos, idx] : gwynDiagonalLeft[_]) {
auto it = gwynDiagonalUp[_].lower_bound(node(pos, INT_MAX));
if (it != gwynDiagonalUp[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
for (auto [pos, idx] : gwynDiagonalRight[_]) {
auto it = gwynDiagonalDown[_].lower_bound(node(pos, INT_MAX));
if (it != gwynDiagonalDown[_].end()) pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
for (auto [pos, idx] : gwynDiagonalDown[_]) {
auto it = gwynDiagonalRight[_].lower_bound(node(pos, INT_MAX));
if (it != gwynDiagonalRight[_].begin()) {
--it;
pq.insert(tuplets(manhattanDistance(idx, it->idx), idx, it->idx));
}
}
}
}
void del(int _) {
switch (a[_].dir) {
case UP :
if (1) {
int o = horizontalCompression::get(a[_].y);
verticalUp[o].erase(node(a[_].x, _));
auto it = verticalDown[o].lower_bound(node(a[_].x, INT_MAX));
if (it != verticalDown[o].begin()) {
--it;
auto ti = verticalUp[o].lower_bound(node(it->pos, INT_MAX));
if (ti != verticalUp[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
if (1) {
int o = mainDiagonalCompression::get(a[_].x-a[_].y);
mainDiagonalUp[o].erase(node(a[_].y, _));
auto it = mainDiagonalRight[o].lower_bound(node(a[_].y, INT_MAX));
if (it != mainDiagonalRight[o].begin()) {
--it;
auto ti = mainDiagonalUp[o].lower_bound(node(it->pos, INT_MAX));
if (ti != mainDiagonalUp[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
if (1) {
int o = gwynDiagonalCompression::get(a[_].x+a[_].y);
gwynDiagonalUp[o].erase(node(a[_].y, _));
auto it = gwynDiagonalLeft[o].lower_bound(node(a[_].y, INT_MAX));
if (it != gwynDiagonalLeft[o].end()) {
auto ti = gwynDiagonalUp[o].lower_bound(node(it->pos, INT_MAX));
if (ti != gwynDiagonalUp[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
break;
case DOWN :
if (1) {
int o = horizontalCompression::get(a[_].y);
verticalDown[o].erase(node(a[_].x, _));
auto it = verticalUp[o].lower_bound(node(a[_].x, INT_MAX));
if (it != verticalUp[o].end()) {
auto ti = verticalDown[o].lower_bound(node(it->pos, INT_MAX));
if (ti != verticalDown[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
if (1) {
int o = mainDiagonalCompression::get(a[_].x-a[_].y);
mainDiagonalDown[o].erase(node(a[_].y, _));
auto it = mainDiagonalLeft[o].lower_bound(node(a[_].y, INT_MAX));
if (it != mainDiagonalLeft[o].end()) {
auto ti = mainDiagonalDown[o].lower_bound(node(it->pos, INT_MAX));
if (ti != mainDiagonalDown[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
if (1) {
int o = gwynDiagonalCompression::get(a[_].x+a[_].y);
gwynDiagonalDown[o].erase(node(a[_].y, _));
auto it = gwynDiagonalRight[o].lower_bound(node(a[_].y, INT_MAX));
if (it != gwynDiagonalRight[o].begin()) {
--it;
auto ti = gwynDiagonalDown[o].lower_bound(node(a[_].y, INT_MAX));
if (ti != gwynDiagonalDown[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
break;
case LEFT :
if (1) {
int o = verticalCompression::get(a[_].x);
horizontalLeft[o].erase(node(a[_].y, _));
auto it = horizontalRight[o].lower_bound(node(a[_].y, INT_MAX));
if (it != horizontalRight[o].begin()) {
--it;
auto ti = horizontalLeft[o].lower_bound(node(it->pos, INT_MAX));
if (ti != horizontalLeft[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
if (1) {
int o = mainDiagonalCompression::get(a[_].x-a[_].y);
mainDiagonalLeft[o].erase(node(a[_].y, _));
auto it = mainDiagonalDown[o].lower_bound(node(a[_].y, INT_MAX));
if (it != mainDiagonalDown[o].begin()) {
--it;
auto ti = mainDiagonalLeft[o].lower_bound(node(it->pos, INT_MAX));
if (ti != mainDiagonalLeft[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
if (1) {
int o = gwynDiagonalCompression::get(a[_].x+a[_].y);
gwynDiagonalLeft[o].erase(node(a[_].y, _));
auto it = gwynDiagonalUp[o].lower_bound(node(a[_].y, INT_MAX));
if (it != gwynDiagonalUp[o].begin()) {
--it;
auto ti = gwynDiagonalLeft[o].lower_bound(node(it->pos, INT_MAX));
if (ti != gwynDiagonalLeft[o].end())
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
break;
case RIGHT :
if (1) {
int o = verticalCompression::get(a[_].x);
horizontalRight[o].erase(node(a[_].y, _));
auto it = horizontalLeft[o].lower_bound(node(a[_].y, INT_MAX));
if (it != horizontalLeft[o].end()) {
auto ti = horizontalRight[o].lower_bound(node(it->pos, INT_MAX));
if (ti != horizontalRight[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
if (1) {
int o = mainDiagonalCompression::get(a[_].x-a[_].y);
mainDiagonalRight[o].erase(node(a[_].y, _));
auto it = mainDiagonalUp[o].lower_bound(node(a[_].y, INT_MAX));
if (it != mainDiagonalUp[o].end()) {
auto ti = mainDiagonalRight[o].lower_bound(node(it->pos, INT_MAX));
if (ti != mainDiagonalRight[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
if (1) {
int o = gwynDiagonalCompression::get(a[_].x+a[_].y);
gwynDiagonalRight[o].erase(node(a[_].x+a[_].y, _));
auto it = gwynDiagonalDown[o].lower_bound(node(a[_].y, INT_MAX));
if (it != gwynDiagonalDown[o].end()) {
auto ti = gwynDiagonalRight[o].lower_bound(node(it->pos, INT_MAX));
if (ti != gwynDiagonalRight[o].begin()) {
--ti;
pq.insert(tuplets(manhattanDistance(it->idx, ti->idx), it->idx, ti->idx));
}
}
}
break;
default :
break;
}
}
void solve() {
vector<int> candidates;
while (!pq.empty()) {
int D = pq.begin()->dis;
candidates.clear();
candidates.shrink_to_fit();
while (!pq.empty() && pq.begin()->dis == D) {
if (cl[pq.begin()->idxOne] || cl[pq.begin()->idxTwo]) {
pq.erase(pq.begin());
continue;
}
candidates.emplace_back(pq.begin()->idxOne);
candidates.emplace_back(pq.begin()->idxTwo);
pq.erase(pq.begin());
}
for (int i : candidates)
if (!cl[i]) {
cl[i] = 1;
del(i);
}
}
}
int main() {
// if (fopen("check.inp", "r")) {
// freopen("check.inp", "r", stdin);
// freopen("check.out", "w", stdout);
// }
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++) {
int x, y; char dir;
cin >> x >> y >> dir;
int d;
switch (dir) {
case 'N' :
d = UP;
break;
case 'W' :
d = LEFT;
break;
case 'S' :
d = DOWN;
break;
default :
d = RIGHT;
}
a[i] = ship(y, x, d);
}
verticalCompression::init();
horizontalCompression::init();
mainDiagonalCompression::init();
gwynDiagonalCompression::init();
init();
solve();
for (int i = 1; i <= n; i++) if (!cl[i]) cout << i << "\n";
}
/*
5
6 6 W
8 10 N
8 6 E
4 2 E
8 0 E
1 2 3 4 5
*/
Compilation message (stderr)
Main.cpp: In member function 'bool node::operator<(const node&) const':
Main.cpp:84:5: warning: control reaches end of non-void function [-Wreturn-type]
84 | }
| ^
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |