说在前面
考试第一题
自己可能还是对这种题不太熟悉,想了将近一个小时emmmm
题目
BZOJ3489传送门
看题可戳传送门
解法
(做法挺多的吧
反正me的做法挺撒币
考虑一个点能对哪些询问造成贡献,不难发现是
L∈[prei+1,i]
L
∈
[
p
r
e
i
+
1
,
i
]
,
R∈[i,nxti−1]
R
∈
[
i
,
n
x
t
i
−
1
]
然后直接树套树硬上就好了emmmm
#include <cstdio>
#include <cstring>
#include <algorithm>
//#define Izumihanako
using namespace std ;
int N , M , a[100005] , uninum , arc[100005] , las_ans ;
int pre[100005] , head[100005] , nxt[100005] ;
struct Unique_Data{
int num , id ;
bool operator < ( const Unique_Data &A ) const {
return num < A.num ;
}
} ud[100005] ;
struct dn_Node{
dn_Node *ch[2] ;
int tag ;
} ;
struct up_Node{
up_Node *ch[2] ;
dn_Node *root ;
} *ROOT ;
template <typename T> void smax( T &x , T y ){ if( x < y ) x = y ; }
void new_dn_Node( dn_Node *&nd ){
nd = new dn_Node() ;
nd->tag = 0 ;
nd->ch[0] = nd->ch[1] = NULL ;
}
void new_up_Node( up_Node *&nd ){
nd = new up_Node() ;
nd->ch[0] = nd->ch[1] = NULL ;
new_dn_Node( nd->root ) ;
}
int uL , uR , dL , dR , x ;
void dn_Modify( dn_Node *&nd , int lf , int rg ){
if( !nd ) new_dn_Node( nd ) ;
if( dL <= lf && rg <= dR ){ smax( nd->tag , x ) ; return ; }
int mid = ( lf + rg ) >> 1 ;
if( dL <= mid ) dn_Modify( nd->ch[0] , lf , mid ) ;
if( dR > mid ) dn_Modify( nd->ch[1] , mid+1,rg ) ;
}
void up_Modify( up_Node *&nd , int lf , int rg ){
if( !nd ) new_up_Node( nd ) ;
if( uL <= lf && rg <= uR ){ dn_Modify( nd->root , 1 , N ) ; return ; }
int mid = ( lf + rg ) >> 1 ;
if( uL <= mid ) up_Modify( nd->ch[0] , lf , mid ) ;
if( uR > mid ) up_Modify( nd->ch[1] , mid+1,rg ) ;
}
void preWork(){
sort( ud + 1 , ud + N + 1 ) , ud[0].num = -0x3f3f3f3f ;
for( int i = 1 ; i <= N ; i ++ ){
if( ud[i].num != ud[i-1].num )
uninum ++ , arc[ uninum ] = ud[i].num ;
a[ ud[i].id ] = uninum ;
} for( int i = 1 ; i <= N ; i ++ )
pre[i] = head[ a[i] ] , head[ a[i] ] = i ;
for( int i = 1 ; i <= N ; i ++ ) head[i] = N + 1 ;
for( int i = N ; i ; i -- )
nxt[i] = head[ a[i] ] , head[ a[i] ] = i ;
for( int i = 1 ; i <= N ; i ++ ){
uL = pre[i] + 1 , uR = i ;
dL = i , dR = nxt[i] - 1 , x = a[i] ;
up_Modify( ROOT , 1 , N ) ;
}
}
int dn_pos , up_pos ;
int dn_Query( dn_Node *nd , int lf , int rg ){
if( !nd ) return 0 ;
int rt = nd->tag , mid = ( lf + rg ) >> 1 ;
if( lf != rg ){
if( dn_pos <= mid ) smax( rt , dn_Query( nd->ch[0] , lf , mid ) ) ;
else smax( rt , dn_Query( nd->ch[1] , mid+1,rg ) ) ;
} return rt ;
}
int up_Query( up_Node *nd , int lf , int rg ){
if( !nd ) return 0 ;
int rt = dn_Query( nd->root , 1 , N ) , mid = ( lf + rg ) >> 1 ;
if( lf != rg ){
if( up_pos <= mid ) smax( rt , up_Query( nd->ch[0] , lf , mid ) ) ;
else smax( rt , up_Query( nd->ch[1] , mid+1,rg ) ) ;
} return rt ;
}
void decode( int &x ){ x = ( x + las_ans )%N + 1 ; }
void solve(){
for( int i = 1 , L , R ; i <= M ; i ++ ){
scanf( "%d%d" , &L , &R ) ;
decode( L ) , decode( R ) ;
if( L > R ) swap( L , R ) ;
if( L <= R ){
up_pos = L , dn_pos = R ;
las_ans = arc[ up_Query( ROOT , 1 , N ) ] ;
printf( "%d\n" , las_ans ) ;
} else las_ans = 0 , printf( "%d\n" , 0 ) ;
}
}
int main(){
#ifdef Izumihanako
freopen( "in.txt" , "r" , stdin ) ;
freopen( "out.txt", "w" , stdout) ;
#endif
scanf( "%d%d" , &N , &M ) ;
for( int i = 1 ; i <= N ; i ++ )
scanf( "%d" , &ud[i].num ) , ud[i].id = i ;
preWork() ; solve() ;
}