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>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
#define ll long long
#define pb push_back
#define s second
#define f first
#define pf push_front
#define inf 100000000000000000
#define bitebi __builtin_popcountll
#define FOR( i , n ) for( int i = 0 ; i < n ; i ++ )
#define YES cout <<"YES\n"
#define NO cout << "NO\n"
#define debug cout << "Here Fine" << endl ;
#define pr pair < int , int >
#define fbo find_by_order // returns iterator
#define ook order_of_key // returns strictly less numbers than key
using namespace std ;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
const double Pi=acos(-1.0);
const double EPS=1E-8;
const int mod = 1000000007 ;
const int mod1 = 998244353 ;
const int N = 2e6 + 10 ;
mt19937 R(time(0));
map < int , int > ma , ma1 ;
#include "books.h"
int pos[ N ] , been[ N ] , s , tt = 0 ;
vector < int > v[ N ] ;
vector < int > vu ;
ll get( int node ){
if( node == s ) tt = 1 ;
been[ node ] = 1 ;
vu.pb( node ) ;
ll cur = 0 ;
for( auto x : v[ node ] ){
// cout << node << " " << x << endl ;
cur = cur + abs( x - node ) ;
if( been[ x ] == 0 ) cur += get( x ) ;
}
return cur ;
}
vector < vector < int > > vvv ;
int mxx[ N ] , mnn[ N ] ;
int roca_mtvare_varskvlavebs_naxavs = 0 ;
map < int , int > mtvare ;
long long minimum_walk(std::vector<int> p, int S){
s = S ;
int n = p.size() ;
ll ans = 0 ;
FOR( i , n ){
v[ i ].pb( p[ i ] ) ;
}
set < int > se ;
pair < int , int > pp ;
FOR( i , n ){
if( been[ i ] == 1 ) continue ;
tt = 0 ;
vu.clear() ;
ans += get( i ) ;
sort( vu.begin() , vu.end() ) ;
int l = vu[ 0 ] ;
int r = vu[ vu.size() - 1 ] ;
// cout << l << " " << r << endl ;
if( tt == 1 ){
pp = { l , r } ;
}
else{
for( auto x : vu ) mtvare[ x ] = vvv.size() , se.insert( x ) ;
mxx[ vvv.size() ] = vu[ vu.size() - 1 ] ;
mnn[ vvv.size() ] = vu[ 0 ] ;
vvv.pb( vu ) ;
roca_mtvare_varskvlavebs_naxavs ++ ;
}
}
//cout << roca_mtvare_varskvlavebs_naxavs << endl ;
//cout << ans << endl ;
int mx = 0 ;
int lst = n - 1 ;
while( true ){
int p ;
if( se.size() == 0 ) break ;
p = *(--se.end() ) ;
if( p <= pp.s ) break ;
if( vvv[ mtvare[ p ] ].size() == 1 && p == lst ){
lst -- ;
se.erase( --se.end() ) ;
} else break ;
}
int ff = 0 ;
while( true ){
int p ;
if( se.size() == 0 ) break ;
p = *se.begin() ;
if( p >= pp.f ) break ;
if( vvv[ mtvare[ p ] ].size() == 1 && p == ff ){
ff ++ ; se.erase( se.begin() ) ;
}
else break ;
}
// cout << ans << endl ;
int l = pp.f , r = pp.s ;
int titu = 0 ;
while( true ){
if( se.size() == 0 ) break ;
int left = - INT_MAX + 10 * N , right = INT_MAX - 10 * N ;
if( *se.begin() < l ) left = *( -- se.lower_bound( l ) ) ;
if( *(--se.end() ) > l ) right = *se.lower_bound( l ) ;
if( right < r || left == -INT_MAX + 10 * N ){
int xx = 0 ;
if( right > r ) xx = 2 ;
ans = ans + xx ;
int mn = INT_MAX , mx = 0 ;
for( auto x : vvv[ mtvare[ right ] ] ){
se.erase( se.find( x ) ) ;
mn = min( mn , x ) ;
mx = max( mx , x ) ;
}
l = min( mn , l ) ;
r = max( mx , r ) ;
continue ;
}
if( titu == -1 || right == INT_MAX - 10 * N ){
int xx = 0 ;
if( right > r ) xx = 2 ;
ans = ans + xx ;
int mn = INT_MAX , mx = 0 ;
for( auto x : vvv[ mtvare[ left ] ] ){
se.erase( se.find( x ) ) ;
mn = min( mn , x ) ;
mx = max( mx , x ) ;
}
l = min( mn , l ) ;
r = max( mx , r ) ;
continue ;
}
int z = r ;
while( true ){
if( *( --se.end() ) == z ){
titu = -1 ; break ;
}
z = *se.upper_bound( z ) ;
if( mnn[ mtvare[ z ] ] < l ){
break ;
}
}
if( titu == -1 ) continue ;
int l1 = l , r1 = r ;
int cost = 0 ;
z = r ;
while( true ){
z = *se.upper_bound( z ) ;
if( z > r1 ){
cost += 2 ;
}
r1 = max( r1 , mxx[ mtvare[ z ] ] ) ;
if( mnn[ mtvare[ z ] ] < l ){
break ;
}
}
int cost2 = 0 ;
l1 = l , r1 = r ; z = r ;
while( true ){
z = *( -- se.lower_bound( z ) ) ;
if( z < l1 ){
cost2 += 2 ;
}
l1 = min( l1 , mnn[ mtvare[ z ] ] ) ;
if( mxx[ mtvare[ z ] ] > r ){
break ;
}
}
set < int > su ;
if( cost < cost2 ){
l1 = l , r1 = r ;
z = r ;
while( true ){
if( *( --se.end() ) == z ){
titu = -1 ; break ;
}
z = *se.upper_bound( z ) ;
su.insert( mtvare[ z ] ) ;
if( mnn[ mtvare[ z ] ] < l ){
break ;
}
}
}
else{
l1 = l , r1 = r ; z = r ;
while( true ){
z = *( -- se.lower_bound( z ) ) ;
su.insert( mtvare[ z ] ) ;
if( mxx[ mtvare[ z ] ] > r ){
break ;
}
}
}
ans += min( cost , cost2 ) ;
for( auto x : su ){
l = min( l , mnn[ x ] ) ;
r = max( r , mxx[ x ] ) ;
for( auto z : vvv[ x ] ) se.erase( se.find( z ) ) ;
}
// cout << " " << left << " " << right << " " << ans << endl ;
}
return ans ;
}
//
// int main() {
// int n, s;
// assert(2 == scanf("%d %d", &n, &s));
// vector<int> p((unsigned) n);
// for(int i = 0; i < n; i++)
// assert(1 == scanf("%d", &p[(unsigned) i]));
// long long res = minimum_walk(p, s);
// printf("%lld\n", res);
// return 0;
// }
Compilation message (stderr)
books.cpp: In function 'long long int minimum_walk(std::vector<int>, int)':
books.cpp:84:7: warning: unused variable 'mx' [-Wunused-variable]
84 | int mx = 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... |