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 ;
#define maxn 200009
#define ll long long
#define fi first
#define se second
#define pb push_back
#define left id<<1
#define right id<<1|1
#define re exit(0);
const int mod = 1e9+7 ;
const int INF = 1e9 ;
const int LOG = 18 ;
typedef vector<int> vi ;
typedef vector<ll> vl ;
typedef pair<int,int> pii ;
typedef vector<pii> vii ;
typedef pair<ll,ll> pll ;
void add ( int &a , int b )
{
a += b ;
if ( a < 0 ) a += mod ;
if ( a >= mod ) a -= mod ;
}
template < typename T > void chkmin (T &a , T b) { if (a>b) a=b ;}
template < typename T > void chkmax (T &a , T b) { if (a<b) a=b ;}
void rf ()
{
freopen ("bai1.inp","r",stdin) ;
// freopen ("bai1.out","w",stdout) ;
}
int n ;
pii a [maxn] ;
bool is_query [maxn] ;
void sub1 ()
{
priority_queue <int> S ;
for ( int i = 1 ; i <= a [1].se ; i ++ ) S.push(a[i].se) ;
int res = 1 ;
int cur = a[1].se ;
while ( !S.empty () )
{
int u = S.top() ; S.pop() ;
if ( cur >= u ) break ;
while ( cur < u ) S . push (a[++cur].se) ;
res ++ ;
}
if ( cur >= n ) cout << res ;
else cout << -1 ;
}
int dp [3009][3009] ;
void sub2 ()
{
int pos ;
for ( int i = 1 ; i <= n ; i ++ ) if ( is_query [i] ) pos = i ;
memset ( dp , 0x3f , sizeof dp ) ;
dp [pos][pos] = 0 ;
for ( int len = 0 ; len <= n-1 ; len ++ )
{
for ( int l = 1 ; l <= n ; l ++ )
{
int r = l + len ;
if ( r > n ) break ;
if ( dp [l][r] > 1e9 ) continue ;
for ( int i = l ; i <= r ; i ++ )
{
chkmin (dp[min(l,a[i].fi)][max(r,a[i].se)],dp[l][r]+1) ;
}
}
}
if ( dp [1][n] > 1e9 ) dp [1][n] = - 1 ;
cout << dp [1][n] ;
}
int range [3009][3009][2] ;
void sub3 ()
{
int pos ;
for ( int i = 1 ; i <= n ; i ++ ) if ( is_query [i] ) pos = i ;
memset ( dp , 0x3f , sizeof dp ) ;
dp [pos][pos] = 0 ;
deque <pii> q ;
q . push_back ({pos,pos}) ;
for ( int i = 1 ; i <= n ; i ++ ) for ( int j = i ; j <= n ; j ++ )
{
if ( i == j ) range [i][j][0] = INF , range [i][j][1] = - INF ;
if ( j > i ) range [i][j][0] = range [i][j-1][0] ;
chkmin (range[i][j][0],a[j].fi) ;
if ( j > i ) range [i][j][1] = range [i][j-1][1] ;
chkmax (range[i][j][1],a[j].se) ;
}
while ( !q.empty() )
{
int l = q.front().fi , r = q.front().se ;
q.pop_front() ;
// state 1 : chosse left
int L = range [l][r][0] , R = r ;
if ( dp [L][R] > dp [l][r] + 1 ) q . push_back ({L,R}) , dp [L][R] = dp [l][r] + 1 ;
// state 2 : chosse right
L = l , R = range [l][r][1] ;
if ( dp [L][R] > dp [l][r] + 1 ) q . push_back ({L,R}) , dp [L][R] = dp [l][r] + 1 ;
// state 3 : in mid
if ( l == r )
{
L = a [l].fi , R = a[l].se ;
if ( dp [L][R] > dp [l][r] + 1 ) q . push_back ({L,R}) , dp [L][R] = dp [l][r] + 1 ;
}
else
{
L = l + 1 , R = r ;
if ( dp [L][R] > dp [l][r] ) q . push_front ({L,R}) , dp [L][R] = dp [l][r] ;
L = l , R = r - 1 ;
if ( dp [L][R] > dp [l][r] ) q . push_front ({L,R}) , dp [L][R] = dp [l][r] ;
}
}
if ( dp [1][n] > INF ) dp [1][n] = - 1 ;
cout << dp [1][n] ;
}
struct shape {
int l , r , w ;
};
vector <shape> Edge [3009][3009] ;
void sub4 ()
{
for ( int i = 1 ; i <= n ; i ++ ) for ( int j = i ; j <= n ; j ++ )
{
if ( i == j ) range [i][j][0] = INF , range [i][j][1] = - INF ;
if ( j > i ) range [i][j][0] = range [i][j-1][0] ;
chkmin (range[i][j][0],a[j].fi) ;
if ( j > i ) range [i][j][1] = range [i][j-1][1] ;
chkmax (range[i][j][1],a[j].se) ;
}
for ( int i = 1 ; i <= n ; i ++ )
{
for ( int j = i ; j <= n ; j ++ )
{
if ( i == j ) Edge [a[i].fi][a[i].se] . pb ({i,i,1}) ;
else
{
int L = range [i][j][0] , R = j ;
Edge [L][R] . pb ({i,j,1}) ;
L = i , R = range [i][j][1] ;
Edge [L][R] . pb ({i,j,1}) ;
L = i + 1 , R = j ;
if ( L >= 1 && R <= n ) Edge [L][R] . pb ({i,j,0}) ;
L = i , R = j - 1 ;
if ( L >= 1 && R <= n ) Edge [L][R] . pb ({i,j,0}) ;
}
}
}
memset ( dp , 0x3f , sizeof dp ) ;
deque <pii> q ;
q . push_back ({1,n}) ;
dp [1][n] = 0 ;
while ( !q.empty () )
{
int l = q.front().fi , r = q.front().se ; q.pop_front() ;
for ( auto x : Edge [l][r] )
{
int L = x.l , R = x.r , w = x.w ;
if ( dp [L][R] > dp [l][r] + w )
{
dp [L][R] = dp [l][r] + w ;
if ( w == 0 ) q.push_front ({L,R}) ;
else q.push_back ({L,R}) ;
}
}
}
for ( int i = 1 ; i <= n ; i ++ )
{
if ( is_query [i] )
{
if ( dp [i][i] > INF ) cout << -1 << "\n" ;
else cout << dp [i][i] << "\n" ;
}
}
}
int main ()
{
ios_base::sync_with_stdio(0) ;
cin.tie(0) ; cout.tie(0) ;
// rf () ;
cin >> n ;
for ( int i = 1 ; i <= n ; i ++ ) cin >> a [i].fi >> a[i].se ;
int nq ; cin >> nq ;
for ( int i = 1 ; i <= nq ; i ++ )
{
int x ; cin >> x ;
is_query [x] = true ;
}
if ( nq == 1 && is_query [1] == true ) sub1 () ;
else if ( nq == 1 && n <= 300 ) sub2 () ;
else if ( nq == 1 && n <= 2500 ) sub3 () ;
else if ( n <= 2500 ) sub4 () ;
}
Compilation message (stderr)
passport.cpp: In function 'void rf()':
passport.cpp:34:10: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
34 | freopen ("bai1.inp","r",stdin) ;
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
passport.cpp: In function 'void sub2()':
passport.cpp:67:16: warning: 'pos' may be used uninitialized in this function [-Wmaybe-uninitialized]
67 | dp [pos][pos] = 0 ;
| ~~~~~~~~~~~~~~^~~
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |