Submission #834075

#TimeUsernameProblemLanguageResultExecution timeMemory
834075LucaIliePort Facility (JOI17_port_facility)C++17
100 / 100
3131 ms239996 KiB
#include <bits/stdc++.h> using namespace std; const int MAX_N = 2e6; const int INF = 1e9; const int MOD = 1e9 + 7; int n; bool vis[MAX_N], side[MAX_N]; int l[MAX_N], r[MAX_N], p[MAX_N]; int indexL[2 * MAX_N + 1], indexR[2 * MAX_N + 1]; struct SEG_TREE { int segTree[4 * MAX_N]; void init() { for ( int v = 0; v < 4 * MAX_N; v++ ) segTree[v] = -INF; } void update( int v, int l, int r, int pos, int x ) { if ( l > pos || r < pos ) return; if ( l == r ) { segTree[v] = x; return; } int mid = (l + r) / 2; update( v * 2 + 1, l, mid, pos, x ); update( v * 2 + 2, mid + 1, r, pos, x ); segTree[v] = max( segTree[v * 2 + 1], segTree[v * 2 + 2] ); } int query( int v, int l, int r, int lq, int rq ) { if ( l > rq || r < lq ) return -INF; if ( lq <= l && r <= rq ) return segTree[v]; int mid = (l + r) / 2; return max( query( v * 2 + 1, l, mid, lq, rq ), query( v * 2 + 2, mid + 1, r, lq, rq ) ); } }; SEG_TREE unvisitedByL, unvisitedByR, visitedByL, visitedByR; void checkBipartit( int u ) { vis[u] = true; unvisitedByL.update( 0, 1, 2 * n, l[u], -INF ); unvisitedByR.update( 0, 1, 2 * n, r[u], -INF ); int rr = unvisitedByL.query( 0, 1, 2 * n, l[u], r[u] ); while ( rr > r[u] ) { int v = indexR[rr]; side[v] = side[u] ^ 1; checkBipartit( v ); rr = unvisitedByL.query( 0, 1, 2 * n, l[u], r[u] ); } int ll = -unvisitedByR.query( 0, 1, 2 * n, l[u], r[u] ); while ( ll < l[u] ) { int v = indexL[ll]; side[v] = side[u] ^ 1; checkBipartit( v ); ll = -unvisitedByR.query( 0, 1, 2 * n, l[u], r[u] ); } } int ll[MAX_N], rr[MAX_N]; int main() { cin.tie( NULL ); cout.tie( NULL ); ios_base::sync_with_stdio( false ); cin >> n; for ( int i = 0; i < n; i++ ) cin >> l[i] >> r[i], p[i] = i; sort( p, p + n, []( int i, int j ) { return l[i] < l[j]; } ); for ( int i = 0; i < n; i++ ) ll[i] = l[p[i]], rr[i] = r[p[i]]; for ( int i = 0; i < n; i++ ) l[i] = ll[i], r[i] = rr[i]; unvisitedByL.init(); unvisitedByR.init(); for ( int i = 0; i < n; i++ ) { unvisitedByL.update( 0, 1, 2 * n, l[i], r[i] ); unvisitedByR.update( 0, 1, 2 * n, r[i], -l[i] ); indexL[l[i]] = i; indexR[r[i]] = i; } int comp = 0; for ( int u = 0; u < n; u++ ) { if ( !vis[u] ) { side[u] = 0; checkBipartit( u ); comp++; } } bool bipartit = true; visitedByR.init(); for ( int i = 0; i < n; i++ ) { if ( side[i] == 1 ) continue; if ( -visitedByR.query( 0, 1, 2 * n, l[i], r[i] ) < l[i] ) bipartit = false; visitedByR.update( 0, 1, 2 * n, r[i], -l[i] ); } visitedByR.init(); for ( int i = 0; i < n; i++ ) { if ( side[i] == 0 ) continue; if ( -visitedByR.query( 0, 1, 2 * n, l[i], r[i] ) < l[i] ) bipartit = false; visitedByR.update( 0, 1, 2 * n, r[i], -l[i] ); } if ( bipartit ) { int ans = 1; for ( int i = 0; i < comp; i++ ) ans = ans * 2 % MOD; cout << ans; } else cout << 0; 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...