题意:
解法:
d[ i] 表示i第几轮被杀.
设i左边第一个比a[ i] 大的位置为j, j的位置可以用单调栈维护.
那么可以用max ( d[ j+ 1 , i- 1 ] + 1 ) 更新d[ i] , max可以用线段树维护和查询.
code:
# include <bits/stdc++.h>
typedef std:: vector< int > VE;
typedef std:: pair< int , int > PI;
# define int long long
# define ll long long
# define ull unsigned long long
# define all ( a, n) a+ 1 , a+ 1 + n
# define ff ( i, n) for ( ll i= 1 ; i<= n; i++ )
# define rff ( i, n) for ( ll i= n; i>= 1 ; i-- )
# define fff ( i, n) for ( ll i= 0 ; i< n; i++ )
# define rfff ( i, n) for ( ll i= n- 1 ; i>= 0 ; i-- )
# define SC ( x) scanf ( "%s" , x)
# define SL ( x) strlen ( x)
# define pss ( a) push_back ( a)
# define ps ( a) push ( a)
# define SZ ( x) ( int ) x. size ( )
# define pee puts ( "" ) ;
# define eee putchar ( ' ' ) ;
# define re readdd ( )
# define pr ( a) printtt ( a)
int readdd ( ) { int x= 0 , f= 1 ; char c= getchar ( ) ;
while ( ! isdigit ( c) && c!= '-' ) c= getchar ( ) ;
if ( c== '-' ) f= - 1 , c= getchar ( ) ;
while ( isdigit ( c) ) x= x* 10 + c- '0' , c= getchar ( ) ;
return f* x; }
void printtt ( int x) { if ( x< 0 ) putchar ( '-' ) , x= - x;
if ( x>= 10 ) printtt ( x/ 10 ) ; putchar ( x% 10 + '0' ) ; }
int gcd ( int a, int b) { return b== 0 ? a: gcd ( b, a% b) ; }
int ppow ( int a, int b, int mod) { a%= mod;
int ans= 1 % mod; while ( b) { if ( b& 1 ) ans= ( long long ) ans* a% mod;
a= ( long long ) a* a% mod; b>>= 1 ; } return ans; }
bool addd ( int a, int b) { return a> b; }
int lowbit ( int x) { return x& - x; }
const int dx[ 4 ] = { 0 , 0 , 1 , - 1 } ;
const int dy[ 4 ] = { 1 , - 1 , 0 , 0 } ;
bool isdigit ( char c) { return c>= '0' && c<= '9' ; }
bool Isprime ( int x) {
for ( int i= 2 ; i* i<= x; i++ ) if ( x% i== 0 ) return 0 ;
return 1 ;
}
void ac ( int x) { if ( x) puts ( "YES" ) ; else puts ( "NO" ) ; }
using namespace std;
const int mod= 1e9 + 7 ;
const int maxm= 2e6 + 5 ;
int a[ maxm] ;
int d[ maxm] ;
int n;
struct Tree {
int a[ maxm<< 2 ] ;
void upd ( int x, int val, int l, int r, int node) {
if ( l== r) {
a[ node] = val; return ;
}
int mid= ( l+ r) / 2 ;
if ( x<= mid) upd ( x, val, l, mid, node* 2 ) ;
else upd ( x, val, mid+ 1 , r, node* 2 + 1 ) ;
a[ node] = max ( a[ node* 2 ] , a[ node* 2 + 1 ] ) ;
}
int ask ( int st, int ed, int l, int r, int node) {
if ( st<= l&& ed>= r) return a[ node] ;
int mid= ( l+ r) / 2 ;
int ans= 0 ;
if ( st<= mid) ans= max ( ans, ask ( st, ed, l, mid, node* 2 ) ) ;
if ( ed> mid) ans= max ( ans, ask ( st, ed, mid+ 1 , r, node* 2 + 1 ) ) ;
return ans;
}
} T;
void solve ( ) {
n= re;
ff ( i, n) a[ i] = re;
stack< int > s;
ff ( i, n) {
while ( s. size ( ) && a[ s. top ( ) ] < a[ i] ) s. pop ( ) ;
if ( s. size ( ) ) {
int l= s. top ( ) ;
int ma= 0 ;
if ( l+ 1 <= i- 1 ) ma= T. ask ( l+ 1 , i- 1 , 1 , n, 1 ) ;
d[ i] = ma+ 1 ;
}
T. upd ( i, d[ i] , 1 , n, 1 ) ;
s. push ( i) ;
}
int ans= T. ask ( 1 , n, 1 , n, 1 ) ;
pr ( ans) ; pee;
}
void Main ( ) {
# ifdef MULTI_CASE
int T; cin>> T; while ( T-- )
# endif
solve ( ) ;
}
void Init ( ) {
# ifdef SYNC_OFF
ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ;
# endif
# ifndef ONLINE_JUDGE
freopen ( "../in.txt" , "r" , stdin ) ;
freopen ( "../out.txt" , "w" , stdout ) ;
# endif
}
signed main ( ) {
Init ( ) ;
Main ( ) ;
return 0 ;
}