题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2333
刚开始看到是动态图问题吓晕了,后来发现没有删边操作,那么就好办多了:由于只需要合并,不需要拆开,所以直接splay暴力维护即可,对于全体最值,本来想打个堆维护的,不过犯了懒,就直接multiset水过去了~
代码(很慢很慢。。。Splay+STL 常数异常巨大):
#include
#include
#include
#include
using namespace std ;
#define MAXN 300010
#define L( t ) left[ t ]
#define R( t ) right[ t ]
#define F( t ) father[ t ]
#define G( t )F(F( t ))
#define M( t ) Max[ t ]
#define V( t ) value[ t ]
#define S( t ) sign[ t ]
#define C( t )( t ==L(F( t )))
#define clear( t )memset( t ,0,sizeof( t ))
#define inf 0x7fffffff
multiset S ;
int left[ MAXN ], right[ MAXN ], father[ MAXN ], Max[ MAXN ], value[ MAXN ], sign[ MAXN ];
int n , m ;
void pushdown(int t ){
if( t &&S( t )){
V( t )+=S( t ),M( t )+=S( t );
S(L( t ))+=S( t ),S(R( t ))+=S( t );
S( t )=0;
}
}
void update(int t ){
pushdown( t );pushdown(L( t )),pushdown(R( t ));
M( t )=max(V( t ),max(M(L( t )),M(R( t ))));
}
void zag(int t ){
pushdown( t );pushdown(R( t ));
int k =R( t ), u =F( t );bool flag =C( t );
F(R( t )=L( k ))= t ;update( t );
F(L( k )= t )= k ;update( k );
F( k )= u ;if( u )if( flag )L( u )= k ;else R( u )= k ;
}
void zig(int t ){
pushdown( t );pushdown(L( t ));
int k =L( t ), u =F( t );bool flag =C( t );
F(L( t )=R( k ))= t ;update( t );
F(R( k )= t )= k ;update( k );
F( k )= u ;if( u )if( flag )L( u )= k ;else R( u )= k ;
}
void splay(int t ){
while(F( t )){
pushdown(G( t )),pushdown(F( t )),pushdown( t );
if(!G( t ))if(C( t ))zig(F( t ));else zag(F( t ));else{
if(C( t )){
if(C(F( t )))zig(G( t ));zig(F( t ));
}else{
if(!C(F( t )))zag(G( t ));zag(F( t ));
}
}
}
}
int MIN(int t ){
for(;L( t ); t =L( t ));return t ;
}
int MAX(int t ){
for(;R( t ); t =R( t ));return t ;
}
int roof(int t ){
splay( t );return MIN( t );
}
int delta =0;
int main( ){
clear( left ),clear( right ),clear( father ),clear( Max ),clear( value ),clear( sign );
Max[0]= value[0]=- inf ;
scanf("%d",&n );
for(int i =0; i ++< n ;){
scanf("%d",&value[ i ]);
Max[ i ]= value[ i ], S.insert( value[ i ]);
}
scanf("%d",&m );
while( m --){
char s[10];scanf("%s", s );
int x , y , u , v ;
if( s[0]=='U'){
scanf("%d%d",&x ,&y );
if(roof( x )!=roof( y )){
splay( x ),splay( y );
pushdown( x ),pushdown( y );
if(M( x )