제출 #370085

#제출 시각아이디문제언어결과실행 시간메모리
370085fishy15Port Facility (JOI17_port_facility)C++14
78 / 100
6100 ms88284 KiB
#include <iostream> #include <iomanip> #include <fstream> #include <vector> #include <array> #include <algorithm> #include <utility> #include <map> #include <queue> #include <set> #include <cmath> #include <cstdio> #include <cstring> #include <numeric> #define ll long long #define ld long double #define eps 1e-8 #define MOD 1000000007 #define INF 0x3f3f3f3f #define INFLL 0x3f3f3f3f3f3f3f3f // change if necessary #define MAXN 1000010 using namespace std; int n; pair<int, int> pts[MAXN]; int l_inv[MAXN]; int r_inv[MAXN]; int vis[MAXN]; // 0 unvis, 1 in first stack, 2 in second stack struct segtree { int st[8 * MAXN]; segtree() { memset(st, 0, sizeof st); } void build(int v = 1, int l = 0, int r = 2 * n) { st[v] = -INF; if (l != r) { int m = (l + r) / 2; build(2 * v, l, m); build(2 * v + 1, m + 1, r); st[v] = -INF; } } void upd(int x, int y, int v = 1, int l = 0, int r = 2 * n) { if (l == r) { st[v] = y; } else { int m = (l + r) / 2; if (x <= m) { upd(x, y, 2 * v, l, m); } else { upd(x, y, 2 * v + 1, m + 1, r); } st[v] = max(st[2 * v], st[2 * v + 1]); } } int qry(int x, int y, int v = 1, int l = 0, int r = 2 * n) { if (r < x || l > y) { return -INF; } else if (x <= l && r <= y) { return st[v]; } else { int m = (l + r) / 2; return max(qry(x, y, 2 * v, l, m), qry(x, y, 2 * v + 1, m + 1, r)); } } }; // left_end is min left end whose right is within a given range // right_end is max right end whose left is within a given range segtree left_end, right_end; void dfs(int x, int c) { left_end.upd(pts[x].second, -INF); right_end.upd(pts[x].first, -INF); vis[x] = c; while (-left_end.qry(pts[x].first, pts[x].second) < pts[x].first) { int left_loc = l_inv[-left_end.qry(pts[x].first, pts[x].second)]; dfs(left_loc, 3 - c); } while (right_end.qry(pts[x].first, pts[x].second) > pts[x].second) { int right_loc = r_inv[right_end.qry(pts[x].first, pts[x].second)]; dfs(right_loc, 3 - c); } } bool check(vector<pair<int, int>> v) { vector<int> tot; for (auto p : v) { tot.push_back(p.first); tot.push_back(p.second); } sort(tot.begin(), tot.end()); vector<int> stack; for (int x : tot) { if (l_inv[x] != -1) { stack.push_back(l_inv[x]); } else { if (stack.empty() || stack.back() != r_inv[x]) { return false; } stack.pop_back(); } } return true; } int main() { cin.tie(0)->sync_with_stdio(0); cin >> n; memset(l_inv, -1, sizeof l_inv); memset(r_inv, -1, sizeof r_inv); for (int i = 0; i < n; i++) { int a, b; cin >> a >> b; pts[i] = {a, b}; l_inv[a] = i; r_inv[b] = i; } left_end.build(); right_end.build(); for (int i = 0; i < n; i++) { left_end.upd(pts[i].second, -pts[i].first); right_end.upd(pts[i].first, pts[i].second); } int cnt = 0; for (int i = 0; i < n; i++) { if (!vis[i]) { cnt++; dfs(i, 1); } } vector<pair<int, int>> a, b; for (int i = 0; i < n; i++) { if (vis[i] == 1) { a.push_back(pts[i]); } else { b.push_back(pts[i]); } } if (check(a) && check(b)) { ll ans = 1; for (int i = 0; i < cnt; i++) { ans += ans; if (ans >= MOD) ans -= MOD; } cout << ans << '\n'; } else { cout << "0\n"; } return 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...