提交时间:2026-04-18 21:29:34

运行 ID: 41362

#pragma GCC optimize("Ofast,no-stack-protector,inline,fast-math,unroll-loops,omit-frame-pointer") #define NDEBUG #include <algorithm> #include <iostream> #include <iterator> #include <queue> #include <set> #include <tuple> #include <vector> using namespace std; using i64 = long long; using Ship = tuple<int, int, char>; constexpr int INF = 0x7f7f7f7f; vector<Ship> ships; #pragma region compare // (x + y, x) struct Cmp1 { bool operator()(int i, int j) const { int x1 = get<0>(ships[i]), y1 = get<1>(ships[i]), x2 = get<0>(ships[j]), y2 = get<1>(ships[j]); return x1 + y1 == x2 + y2 ? x1 < x2 : x1 + y1 < x2 + y2; } }; // (x - y, x) struct Cmp2 { bool operator()(int i, int j) const { int x1 = get<0>(ships[i]), y1 = get<1>(ships[i]), x2 = get<0>(ships[j]), y2 = get<1>(ships[j]); return x1 - y1 == x2 - y2 ? x1 < x2 : x1 - y1 < x2 - y2; } }; // (y, x) struct Cmp3 { bool operator()(int i, int j) const { int x1 = get<0>(ships[i]), y1 = get<1>(ships[i]), x2 = get<0>(ships[j]), y2 = get<1>(ships[j]); return y1 == y2 ? x1 < x2 : y1 < y2; } }; // (x, y) struct Cmp4 { bool operator()(int i, int j) const { int x1 = get<0>(ships[i]), y1 = get<1>(ships[i]), x2 = get<0>(ships[j]), y2 = get<1>(ships[j]); return x1 == x2 ? y1 < y2 : x1 < x2; } }; #pragma endregion int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int N; cin >> N; vector<int> ship_S, ship_W, ship_E, ship_N; for (int i = 0; i < N; ++i) { int x, y; char d; cin >> x >> y >> d; ships.push_back(make_tuple(x, y, d)); if (d == 'S') ship_S.push_back(i); else if (d == 'N') ship_N.push_back(i); else if (d == 'E') ship_E.push_back(i); else if (d == 'W') ship_W.push_back(i); } priority_queue<tuple<int, int, int>> events; #pragma region initialize int lst = -1; set<int, Cmp1> SE; vector<int> del_SE; SE.insert(ship_S.begin(), ship_S.end()); SE.insert(ship_E.begin(), ship_E.end()); for (int i : SE) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'E' && d2 == 'S' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, i, lst); lst = i; } lst = -1; set<int, Cmp1> NW; vector<int> del_NW; NW.insert(ship_N.begin(), ship_N.end()); NW.insert(ship_W.begin(), ship_W.end()); for (int i : NW) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'N' && d2 == 'W' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, i, lst); lst = i; } lst = -1; set<int, Cmp2> NE; vector<int> del_NE; NE.insert(ship_N.begin(), ship_N.end()); NE.insert(ship_E.begin(), ship_E.end()); for (int i : NE) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'E' && d2 == 'N' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, i, lst); lst = i; } lst = -1; set<int, Cmp2> SW; vector<int> del_SW; SW.insert(ship_S.begin(), ship_S.end()); SW.insert(ship_W.begin(), ship_W.end()); for (int i : SW) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'S' && d2 == 'W' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, i, lst); lst = i; } lst = -1; set<int, Cmp3> EW; vector<int> del_EW; EW.insert(ship_W.begin(), ship_W.end()); EW.insert(ship_E.begin(), ship_E.end()); for (int i : EW) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'E' && d2 == 'W' && y1 == y2) events.emplace((x1 - x2) >> 1, i, lst); lst = i; } lst = -1; set<int, Cmp4> SN; vector<int> del_SN; SN.insert(ship_S.begin(), ship_S.end()); SN.insert(ship_N.begin(), ship_N.end()); for (int i : SN) { if (lst == -1) { lst = i; continue; } int x1 = get<0>(ships[lst]), y1 = get<1>(ships[lst]); char d1 = get<2>(ships[lst]); int x2 = get<0>(ships[i]), y2 = get<1>(ships[i]); char d2 = get<2>(ships[i]); if (d1 == 'S' && d2 == 'N' && x1 == x2) events.emplace((y1 - y2) >> 1, i, lst); lst = i; } #pragma endregion auto erase_all = [&]() { int l = -1, r = -1; sort(del_EW.begin(), del_EW.end(), Cmp3()); for (int x : del_EW) { set<int, Cmp3>::iterator itr = EW.find(x); if (itr == EW.end()) continue; if (itr == EW.begin()) { EW.erase(itr); continue; } else if (next(itr) == EW.end()) { EW.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'W' && y1 == y2) events.emplace((x1 - x2) >> 1, l, r); } l = pre; } r = *next(itr); EW.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'W' && y1 == y2) events.emplace((x1 - x2) >> 1, l, r); } del_EW.clear(); l = -1; r = -1; sort(del_NE.begin(), del_NE.end(), Cmp2()); for (int x : del_NE) { set<int, Cmp2>::iterator itr = NE.find(x); if (itr == NE.end()) continue; if (itr == NE.begin()) { NE.erase(itr); continue; } else if (next(itr) == NE.end()) { NE.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'N' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, l, r); } l = pre; } r = *next(itr); NE.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'N' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, l, r); } del_NE.clear(); l = -1; r = -1; sort(del_NW.begin(), del_NW.end(), Cmp1()); for (int x : del_NW) { set<int, Cmp1>::iterator itr = NW.find(x); if (itr == NW.end()) continue; if (itr == NW.begin()) { NW.erase(itr); continue; } else if (next(itr) == NW.end()) { NW.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'N' && d2 == 'W' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, l, r); } l = pre; } r = *next(itr); NW.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'N' && d2 == 'W' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, l, r); } del_NW.clear(); l = -1; r = -1; sort(del_SE.begin(), del_SE.end(), Cmp1()); for (int x : del_SE) { set<int, Cmp1>::iterator itr = SE.find(x); if (itr == SE.end()) continue; if (itr == SE.begin()) { SE.erase(itr); continue; } else if (next(itr) == SE.end()) { SE.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'S' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, l, r); } l = pre; } r = *next(itr); SE.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'E' && d2 == 'S' && x1 + y1 == x2 + y2) events.emplace(x1 - x2, l, r); } del_SE.clear(); l = -1; r = -1; sort(del_SN.begin(), del_SN.end(), Cmp4()); for (int x : del_SN) { set<int, Cmp4>::iterator itr = SN.find(x); if (itr == SN.end()) continue; if (itr == SN.begin()) { SN.erase(itr); continue; } else if (next(itr) == SN.end()) { SN.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'S' && d2 == 'N' && x1 == x2) events.emplace((y1 - y2) >> 1, l, r); } l = pre; } r = *next(itr); SN.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'S' && d2 == 'N' && x1 == x2) events.emplace((y1 - y2) >> 1, l, r); } del_SN.clear(); l = -1; r = -1; sort(del_SW.begin(), del_SW.end(), Cmp2()); for (int x : del_SW) { set<int, Cmp2>::iterator itr = SW.find(x); if (itr == SW.end()) continue; if (itr == SW.begin()) { SW.erase(itr); continue; } else if (next(itr) == SW.end()) { SW.erase(itr); r = -1; continue; } int pre = *prev(itr); if (pre != l) { if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'S' && d2 == 'W' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, l, r); } l = pre; } r = *next(itr); SW.erase(itr); } if (l != -1 && r != -1) { int x1 = get<0>(ships[l]), y1 = get<1>(ships[l]); char d1 = get<2>(ships[l]); int x2 = get<0>(ships[r]), y2 = get<1>(ships[r]); char d2 = get<2>(ships[r]); if (d1 == 'S' && d2 == 'W' && x1 - y1 == x2 - y2) events.emplace(x1 - x2, l, r); } del_SW.clear(); }; vector<int> del(N, INF); while (!events.empty()) { tuple<int, int, int> e = events.top(); events.pop(); int t = -get<0>(e); int u = get<1>(e); int v = get<2>(e); if (del[u] < t || del[v] < t) continue; del[u] = del[v] = t; #pragma region update char d1 = get<2>(ships[u]), d2 = get<2>(ships[v]); if (d1 == 'N') { if (d2 == 'S') { del_SN.push_back(u); del_SN.push_back(v); del_NE.push_back(u); del_NW.push_back(u); del_SE.push_back(v); del_SW.push_back(v); } else if (d2 == 'E') { del_NE.push_back(u); del_NE.push_back(v); del_NW.push_back(u); del_SN.push_back(u); del_EW.push_back(v); del_SE.push_back(v); } else if (d2 == 'W') { del_NW.push_back(u); del_NW.push_back(v); del_NE.push_back(u); del_SN.push_back(u); del_EW.push_back(v); del_SW.push_back(v); } } else if (d1 == 'S') { if (d2 == 'N') { del_SN.push_back(u); del_SN.push_back(v); del_SE.push_back(u); del_SW.push_back(u); del_NE.push_back(v); del_NW.push_back(v); } else if (d2 == 'E') { del_SE.push_back(u); del_SE.push_back(v); del_SW.push_back(u); del_SN.push_back(u); del_EW.push_back(v); del_NE.push_back(v); } else if (d2 == 'W') { del_SW.push_back(u); del_SW.push_back(v); del_SE.push_back(u); del_SN.push_back(u); del_EW.push_back(v); del_NW.push_back(v); } } else if (d1 == 'E') { if (d2 == 'W') { del_EW.push_back(u); del_EW.push_back(v); del_SE.push_back(u); del_NE.push_back(u); del_SW.push_back(v); del_NW.push_back(v); } else if (d2 == 'S') { del_SE.push_back(u); del_SE.push_back(v); del_NE.push_back(u); del_EW.push_back(u); del_SW.push_back(v); del_SN.push_back(v); } else if (d2 == 'N') { del_NE.push_back(u); del_NE.push_back(v); del_SE.push_back(u); del_EW.push_back(u); del_NW.push_back(v); del_SN.push_back(v); } } else if (d1 == 'W') { if (d2 == 'E') { del_EW.push_back(u); del_EW.push_back(v); del_NW.push_back(u); del_SW.push_back(u); del_SE.push_back(v); del_NE.push_back(v); } else if (d2 == 'N') { del_NW.push_back(u); del_NW.push_back(v); del_SW.push_back(u); del_EW.push_back(u); del_SN.push_back(v); del_NE.push_back(v); } else if (d2 == 'S') { del_SW.push_back(u); del_SW.push_back(v); del_NW.push_back(u); del_EW.push_back(u); del_SE.push_back(v); del_SN.push_back(v); } } #pragma endregion if (events.empty() || get<0>(events.top()) != t) erase_all(); } for (int i = 0; i < N; ++i) { if (del[i] >= INF) cout << i + 1 << '\n'; } return 0; }