제출 #833985

#제출 시각아이디문제언어결과실행 시간메모리
833985LucaIliePort Facility (JOI17_port_facility)C++17
78 / 100
6040 ms226156 KiB
#include <bits/stdc++.h> using namespace std; const int MAX_N = 1e6; const int MOD = 1e9 + 7; int n; bool bipartit = true; bool vis[MAX_N], side[MAX_N]; int l[MAX_N], r[MAX_N]; int indexL[2 * MAX_N + 1], indexR[2 * MAX_N + 1]; struct info { int minn, maxx; info operator + ( info x ) { return { min( minn, x.minn ), max( maxx, x.maxx ) }; } }; struct SEG_TREE { info segTree[4 * MAX_N]; void init() { for ( int v = 0; v < 4 * MAX_N; v++ ) segTree[v] = { 2 * n + 1, 0 }; } void update( int v, int l, int r, int pos, info 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] = segTree[v * 2 + 1] + segTree[v * 2 + 2]; } info query( int v, int l, int r, int lq, int rq ) { if ( l > rq || r < lq ) return { 2 * n + 1, 0 }; if ( lq <= l && r <= rq ) return segTree[v]; int mid = (l + r) / 2; return query( v * 2 + 1, l, mid, lq, rq ) + query( v * 2 + 2, mid + 1, r, lq, rq ); } }; SEG_TREE unvisitedByL, unvisitedByR, visitedByL0, visitedByR0, visitedByL1, visitedByR1; void checkBipartit( int u ) { vis[u] = true; unvisitedByL.update( 0, 1, 2 * n, l[u], { 2 * n + 1, 0 } ); unvisitedByR.update( 0, 1, 2 * n, r[u], { 2 * n + 1, 0 } ); if ( side[u] == 0 ) { visitedByL0.update( 0, 1, 2 * n, l[u], { r[u], r[u] } ); visitedByR0.update( 0, 1, 2 * n, r[u], { l[u], l[u] } ); } else { visitedByL1.update( 0, 1, 2 * n, l[u], { r[u], r[u] } ); visitedByR1.update( 0, 1, 2 * n, r[u], { l[u], l[u] } ); } while ( unvisitedByL.query( 0, 1, 2 * n, l[u], r[u] ).maxx > r[u] ) { int v = indexR[unvisitedByL.query( 0, 1, 2 * n, l[u], r[u] ).maxx]; side[v] = side[u] ^ 1; checkBipartit( v ); } while ( unvisitedByR.query( 0, 1, 2 * n, l[u], r[u] ).minn < l[u] ) { int v = indexL[unvisitedByR.query( 0, 1, 2 * n, l[u], r[u] ).minn]; side[v] = side[u] ^ 1; checkBipartit( v ); } bool exista0 = false, exista1 = false; if ( visitedByL0.query( 0, 1, 2 * n, l[u], r[u] ).maxx > r[u] || visitedByR0.query( 0, 1, 2 * n, l[u], r[u] ).minn < l[u] ) exista0 = true; if ( visitedByL1.query( 0, 1, 2 * n, l[u], r[u] ).maxx > r[u] || visitedByR1.query( 0, 1, 2 * n, l[u], r[u] ).minn < l[u] ) exista1 = true; if ( exista0 && exista1 ) bipartit = false; } int main() { cin >> n; for ( int i = 0; i < n; i++ ) cin >> l[i] >> r[i]; unvisitedByL.init(); unvisitedByR.init(); visitedByL0.init(); visitedByR0.init(); visitedByL1.init(); visitedByR1.init(); for ( int i = 0; i < n; i++ ) { unvisitedByL.update( 0, 1, 2 * n, l[i], { r[i], r[i] } ); unvisitedByR.update( 0, 1, 2 * n, r[i], { l[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++; } } 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...