传送门
唯一能自己做出来的一道(呜呜呜) 暴力做法是考虑
d
p
dp
d p 出
f
0
/
1
,
x
,
y
f_{0/1,x,y}
f 0 / 1 , x , y 表示最后一个在
A
/
B
A/B
A / B ,
A
,
B
A,B
A , B 选了
x
,
y
x,y
x , y 合不合法,那么发现对于某个特定的
x
+
y
x+y
x + y ,合法的
x
x
x 是一个区间,所以记录左右端点
O
(
1
)
O(1)
O ( 1 ) 转移
#include <bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 1e6 + 50 ;
int read ( ) {
int cnt= 0 , f= 1 ; char ch= 0 ;
while ( ! isdigit ( ch) ) { ch= getchar ( ) ; if ( ch== '-' ) f= - 1 ; }
while ( isdigit ( ch) ) cnt= cnt* 10 + ( ch- '0' ) , ch= getchar ( ) ;
return cnt* f;
}
int n, a[ N] , b[ N] ;
int l1[ N] , r1[ N] , l2[ N] , r2[ N] ;
void work ( int typ, int u, int c) {
if ( u== 0 ) return ; assert ( c>= 0 ) ;
if ( typ== 0 ) {
if ( l1[ u- 1 ] <= c- 1 && c- 1 <= r1[ u- 1 ] && a[ u- 1 ] <= a[ u] ) work ( 0 , u- 1 , c- 1 ) ;
else work ( 1 , u- 1 , c- 1 ) ; cout<< "A" ;
}
if ( typ== 1 ) {
if ( l1[ u- 1 ] <= c&& c<= r1[ u- 1 ] && a[ u- 1 ] <= b[ u] ) work ( 0 , u- 1 , c) ;
else work ( 1 , u- 1 , c) ; cout<< "B" ;
}
}
int main ( ) {
n= read ( ) ;
for ( int i= 1 ; i<= n+ n; i++ ) a[ i] = read ( ) ;
for ( int i= 1 ; i<= n+ n; i++ ) b[ i] = read ( ) ;
memset ( r1, - 1 , sizeof ( r1) ) ;
memset ( r2, - 1 , sizeof ( r2) ) ;
memset ( l1, 0x3f , sizeof ( l1) ) ;
memset ( l2, 0x3f , sizeof ( l2) ) ;
l1[ 1 ] = 1 ; r1[ 1 ] = 1 ; l2[ 1 ] = 0 ; r2[ 1 ] = 0 ;
for ( int i= 2 ; i<= n+ n; i++ ) {
if ( a[ i] >= a[ i- 1 ] ) l1[ i] = min ( l1[ i- 1 ] + 1 , l1[ i] ) , r1[ i] = max ( r1[ i] , r1[ i- 1 ] + 1 ) ;
if ( a[ i] >= b[ i- 1 ] ) l1[ i] = min ( l2[ i- 1 ] + 1 , l1[ i] ) , r1[ i] = max ( r1[ i] , r2[ i- 1 ] + 1 ) ;
if ( b[ i] >= a[ i- 1 ] ) l2[ i] = min ( l2[ i] , l1[ i- 1 ] ) , r2[ i] = max ( r2[ i] , r1[ i- 1 ] ) ;
if ( b[ i] >= b[ i- 1 ] ) l2[ i] = min ( l2[ i] , l2[ i- 1 ] ) , r2[ i] = max ( r2[ i] , r2[ i- 1 ] ) ;
if ( l1[ i] > r1[ i] && l2[ i] > r2[ i] ) { puts ( "-1" ) ; return 0 ; }
}
if ( l1[ n+ n] <= n&& n<= r1[ n+ n] ) { work ( 0 , n+ n, n) ; return 0 ; }
if ( l2[ n+ n] <= n&& n<= r2[ n+ n] ) { work ( 1 , n+ n, n) ; return 0 ; }
puts ( "-1" ) ; return 0 ;
}