【BZOJ】1500 [NOI2005]维修数列 【splay】
2014-09-30 22:23
429 查看
传送门:【BZOJ】1500 [NOI2005]维修数列
题目分析:题目很简单,就维护左连续最大和,右连续最大和,以及区间最大和,区间和,是否反转,是否被置为相同即可。
一开始漏考虑了翻转的时候左右连续最大和也要翻转,还有就是区间最大和可能等于自身。。
明明很简单的题。。却调了那么久。。不说了。。
代码如下:
题目分析:题目很简单,就维护左连续最大和,右连续最大和,以及区间最大和,区间和,是否反转,是否被置为相同即可。
一开始漏考虑了翻转的时候左右连续最大和也要翻转,还有就是区间最大和可能等于自身。。
明明很简单的题。。却调了那么久。。不说了。。
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std ; typedef long long LL ; #pragma comment(linker, "/STACK:16777216") #define Log( i , a , b ) for ( int i = a ; ( 1 << i ) <= b ; ++ i ) #define rep( i , a , b ) for ( int i = a ; i < b ; ++ i ) #define For( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next ) #define clr( a , x ) memset ( a , x , sizeof a ) #define cpy( a , x ) memcpy ( a , x , sizeof a ) const int MAXN = 1000005 ; const int INF = 100000000 ; struct Node* null ; struct Node* root ; struct Node { Node* f ; Node* c[2] ; int v ; int s ; int sum ; int Lmax ; int Mmax ; int Rmax ; int flip ; int same ; inline int max ( const int& a , const int& b ) { if ( a > b ) return a ; return b ; } inline int max ( const int& a , const int& b , const int& c ) { if ( a > b ) { if ( a > c ) return a ; return c ; } else { if ( b > c ) return b ; return c ; } } inline void newnode ( Node* fa , int val ) { s = 1 ; f = fa ; same = flip = 0 ; c[0] = c[1] = null ; v = sum = Lmax = Mmax = Rmax = val ; } inline void link_child ( Node* o , int d ) { c[d] = o ; o->f = this ; } inline void make_flip () { if ( this == null ) return ; swap ( c[0] , c[1] ) ; swap ( Lmax , Rmax ) ; flip ^= 1 ; } inline void make_same ( int val ) { if ( this == null ) return ; v = val ; same = 1 ; sum = s * v ; Lmax = Rmax = Mmax = max ( v , sum ) ; } void push_up () { s = c[0]->s + 1 + c[1]->s ; sum = c[0]->sum + v + c[1]->sum ; Lmax = max ( c[0]->Lmax , c[0]->sum + v , c[0]->sum + v + c[1]->Lmax ) ; Rmax = max ( c[1]->Rmax , c[1]->sum + v , c[1]->sum + v + c[0]->Rmax ) ; Mmax = max ( v , c[0]->Mmax , c[1]->Mmax ) ;//这里忘记Mmax可能等于v了,WA死。。 Mmax = max ( Mmax , max ( c[0]->Rmax + v , c[1]->Lmax + v ) , c[0]->Rmax + v + c[1]->Lmax ) ; } void push_down () { if ( flip ) { c[0]->make_flip () ; c[1]->make_flip () ; flip = 0 ; } if ( same ) { c[0]->make_same ( v ) ; c[1]->make_same ( v ) ; same = 0 ; } } void sign_down () { if ( f != null ) f->sign_down () ; push_down () ; } void rotate ( int d ) { Node* p = f ; Node* gp = f->f ; p->link_child ( c[d] , !d ) ; if ( gp != null ) gp->link_child ( this , p == gp->c[1] ) ; else f = null ; link_child ( p , d ) ; p->push_up () ; } void splay ( Node* r = null ) { sign_down () ; while ( f != r ) { if ( f->f == r ) { this == f->c[0] ? rotate ( 1 ) : rotate ( 0 ) ; } else { if ( f == f->f->c[0] ) { this == f->c[0] ? f->rotate ( 1 ) : rotate ( 0 ) ; rotate ( 1 ) ; } else { this == f->c[1] ? f->rotate ( 0 ) : rotate ( 1 ) ; rotate ( 0 ) ; } } } push_up () ; if ( r == null ) root = this ; } } ; struct Splay { Node node[MAXN] ; Node* cur ; Node* pool[MAXN] ; int top ; void push_back ( Node* o ) { if ( o == null ) return ; pool[top ++] = o ; push_back ( o->c[0] ) ; push_back ( o->c[1] ) ; } void select ( int kth , Node* r ) { ++ kth ; Node* o = root ; while ( o != null ) { o->push_down () ; int s = o->c[0]->s ; if ( s + 1 == kth ) break ; if ( kth <= s ) o = o->c[0] ; else o = o->c[1] , kth -= s + 1 ; } o->splay ( r ) ; } Node* get ( int l , int r ) { select ( l - 1 , null ) ; select ( r + 1 , root ) ; return root->c[1]->c[0] ; } void reverse ( int l , int r ) { Node* o = get ( l , r ) ; o->make_flip () ; o->splay () ; } void set ( int l , int r , int val ) { Node* o = get ( l , r ) ; o->make_same ( val ) ; o->splay () ; } void remove ( int l , int r ) { Node* o = get ( l , r ) ; root->c[1]->c[0] = null ; root->c[1]->push_up () ; root->push_up () ; push_back ( o ) ; } void insert ( Node* o , int pos ) { get ( pos + 1 , pos ) ; root->c[1]->link_child ( o , 0 ) ; root->c[1]->push_up () ; root->push_up () ; o->splay () ; } void query_sum ( int l , int r ) { printf ( "%d\n" , get ( l , r )->sum ) ; } void query_max_sum () { printf ( "%d\n" , root->Mmax ) ; } Node* make_new_tree ( int num[] , int n ) { Node* x = null ; Node* o = null ; For ( i , 1 , n ) { if ( top ) o = pool[-- top] ; else o = cur ++ ; o->newnode ( null , num[i] ) ; o->link_child ( x , 0 ) ; o->push_up () ; x = o ; } return o ; } void clear () { top = 0 ; cur = node ; null = cur ++ ; null->newnode ( null , -INF ) ; null->s = 0 ; null->sum = 0 ; root = cur ++ ; root->newnode ( null , -INF ) ; root->c[1] = cur ++ ; root->c[1]->newnode ( root , -INF ) ; root->push_up () ; } } S ; int num[MAXN] ; char op[20] ; int n , m ; void solve () { int pos , tot , x ; S.clear () ; For ( i , 1 , n ) scanf ( "%d" , &num[i] ) ; Node* o = S.make_new_tree ( num , n ) ; S.insert ( o , 0 ) ; while ( m -- ) { scanf ( "%s" , op ) ; if ( op[0] == 'I' ) { scanf ( "%d%d" , &pos , &tot ) ; For ( i , 1 , tot ) scanf ( "%d" , &num[i] ) ; Node* o = S.make_new_tree ( num , tot ) ; S.insert ( o , pos ) ; } else if ( op[0] == 'D' ) { scanf ( "%d%d" , &pos , &tot ) ; S.remove ( pos , pos + tot - 1 ) ; } else if ( op[2] == 'K' ) { scanf ( "%d%d%d" , &pos , &tot , &x ) ; S.set ( pos , pos + tot - 1 , x ) ; } else if ( op[0] == 'R' ) { scanf ( "%d%d" , &pos , &tot ) ; S.reverse ( pos , pos + tot - 1 ) ; } else if ( op[0] == 'G' ) { scanf ( "%d%d" , &pos , &tot ) ; S.query_sum ( pos , pos + tot - 1 ) ; } else S.query_max_sum () ; } } int main () { while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ; return 0 ; }
相关文章推荐
- BZOJ 1500 【NOI2005 D1T2】 维修数列 Splay
- [BZOJ1500][NOI2005]维修数列(splay)
- _bzoj1500 [NOI2005]维修数列【真·Splay】
- BZOJ 1500 [NOI 2005] 维修数列 (splay 模板)
- [bzoj1500 维修数列](NOI2005) (splay)
- bzoj 1500: [NOI2005]维修数列(splay)
- BZOJ 1500: [NOI2005]维修数列 splay
- [bzoj1500][NOI2005]维修数列——splay
- BZOJ 1500 [NOI2005]维修数列 (splay)
- 【BZOJ1500】【NOI2005】维修数列(Splay)
- 【splay】BZOJ 1500: [NOI2005]维修数列
- BZoj 1500 [NOI2005]维修数列 (Splay 模板)
- bzoj 1500: [NOI2005]维修数列 splay
- BZOJ 1500 NOI 2005 维修数列 Splay
- [BZOJ1500][NOI2005]维修数列(Splay)
- [BZOJ1500]NOI2005 维修数列|splay
- BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】
- [NOI2005] [BZOJ1500] 维修数列 - splay
- 【bzoj1500】[NOI2005]维修数列 Splay
- 【bzoj1500】[NOI2005]维修数列 Splay