This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5; // TODO: fix
struct Node {
int L; int R; int cnt;
Node() { L = R = cnt = 0; }
} T[N * 40];
int pos[N * 2][2], segl[N * 2], segr[N * 2];
vector< pair<int,int> > G[N * 40];
int color[N * 40], cnt; // for bipartite checking
bool vis[N * 40]; // for BFS
int n, peak, version;
pair<int,int> a[N];
#define mid ((l + r) >> 1)
int build(int l, int r) {
if (l == r) {
pos[l][1] = ++peak; // on
T[peak].L = T[peak].R = peak; T[peak].cnt = 1;
pos[l][0] = ++peak; // off
T[peak].L = T[peak].R = peak;
return peak; // currently off
}
int le = build(l, mid), ri = build(mid + 1, r);
++peak; T[peak].L = le; T[peak].R = ri;
return peak;
}
int upd(int v, int l, int r, int p, int val) {
if (l > r || l > p || r < p) return v;
if (l == r) return pos[p][val];
int le = upd(T[v].L, l, mid, p, val);
int ri = upd(T[v].R, mid + 1, r, p, val);
++peak; T[peak].L = le; T[peak].R = ri;
T[peak].cnt = T[T[peak].L].cnt + T[T[peak].R].cnt;
//printf("new node: %d -> L = %d R = %d\n", peak, T[peak].L, T[peak].R);
return peak;
}
void add(int cur, int v, int l, int r, int L, int R) {
if (l > r || R < l || L > r) return;
if (L <= l && r <= R) {
// cur and v belong to different sides in the bipartite graph
if (!T[v].cnt) return; // off
G[cur].push_back(make_pair(1, v)); G[v].push_back(make_pair(1, cur));
vis[v] = true;
return;
}
add(cur, T[v].L, l, mid, L, R); add(cur, T[v].R, mid + 1, r, L, R);
}
#undef mid
void dfs(int u) {
for (auto e : G[u]) {
int v = e.second, id = e.first;
if (color[v] == -1) {
color[v] = (color[u] ^ id); dfs(v);
} else if (color[v] != -1 && color[v] != (color[u] ^ id)) {
printf("0\n"); exit(0); // invalid
}
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i].first >> a[i].second;
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i) {
segl[a[i].first] = i;
segr[a[i].second] = i;
}
version = build(1, 2 * n);
for (int lef = 1; lef <= 2 * n; ++lef) {
int del = segr[lef - 1];
if (del) {
// delete
version = upd(version, 1, 2 * n, lef - 1, 0);
}
int cur = segl[lef];
if (!cur) continue;
int rig = a[cur].second;
// add
add(pos[rig][1], version, 1, 2 * n, lef, rig);
// update
version = upd(version, 1, 2 * n, rig, 1);
}
// BFS
queue <int> qu;
for (int i = 1; i <= peak; ++i) if (vis[i]) qu.push(i);
while(!qu.empty()) {
int u = qu.front(); qu.pop();
if (T[T[u].L].cnt) {
G[u].push_back(make_pair(0, T[u].L)); G[T[u].L].push_back(make_pair(0, u));
if (!vis[T[u].L]) {
qu.push(T[u].L);
vis[T[u].L] = true;
}
}
if (T[T[u].R].cnt) {
G[u].push_back(make_pair(0, T[u].R)); G[T[u].R].push_back(make_pair(0, u));
if (!vis[T[u].R]) {
qu.push(T[u].R);
vis[T[u].R] = true;
}
}
}
// check for bipartite graph
memset(color, -1, sizeof color);
for (int i = 1; i <= 2 * n; ++i) if (segr[i] && color[pos[i][1]] == -1) {
color[pos[i][1]] = 0; ++cnt; dfs(pos[i][1]);
}
int ans = 1;
while(cnt-- > 0) ans = 2LL * ans % (int)(1e9 + 7);
printf("%d\n", ans);
}
# | 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... |