【splay】hdu 4453 2012杭州赛区A题

http://acm.hdu.edu.cn/showproblem.php?pid=4453

      普通的splay,但是出题人很无聊的给题目加上了很多限制,使得双向链表也可以处理,但是我还是比较喜欢splay这种数据结构,试了一下现在手写无压力。。

hdu4453_splay
  1 //By Lin
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define maxn 100050
  6 using namespace std;
  7 
  8 struct    SplayNode{
  9     SplayNode *fa,*ch[2];
 10     int    key,add,size;
 11     bool rev;
 12     SplayNode(int key = 0 ){
 13         fa = ch[0] = ch[1] = NULL;
 14         this->key = key;
 15         size = 1;
 16         add = 0 , rev = false;
 17     }
 18     void clear(){
 19         if ( ch[0] ) ch[0]->clear();
 20         if ( ch[1] ) ch[1]->clear();
 21         delete this;
 22     }
 23     void updata(){
 24         size = (ch[0]?ch[0]->size:0)+(ch[1]?ch[1]->size:0)+1;
 25     }
 26     void down(){
 27         if ( add ){
 28             if ( ch[0] ) ch[0]->key += add , ch[0]->add += add;
 29             if ( ch[1] ) ch[1]->key += add , ch[1]->add += add;
 30             add = 0;
 31         }
 32         if ( rev ) {
 33             swap( ch[0] , ch[1] );
 34             if ( ch[0] ) ch[0]->rev ^= 1; 
 35             if ( ch[1] ) ch[1]->rev ^= 1;
 36             rev = false;
 37         }
 38     }
 39     SplayNode* maxnode(){
 40         down();
 41         if ( ch[1] ) return ch[1]->maxnode();
 42         return this;
 43     }
 44     void show(){
 45         if ( ch[0] ) ch[0]->show();
 46         printf("%d ", key );
 47         if ( ch[1] ) ch[1]->show();
 48     }
 49 }*root,*tmp;
 50 SplayNode* build(int data[],int l,int r,SplayNode* fa = NULL){
 51     int mid = (l+r)/2;
 52     SplayNode *ret = new SplayNode(data[mid]);
 53     ret->fa = fa;
 54     if ( l<mid ) ret->ch[0] = build(data,l,mid-1,ret);
 55     if ( mid<r ) ret->ch[1] = build(data,mid+1,r,ret);
 56     ret->updata();
 57     return ret;
 58 }
 59 void Rotate(SplayNode* tmp){
 60     SplayNode* y = tmp->fa;
 61     if ( tmp->fa = y->fa ) 
 62         y->fa->ch[y->fa->ch[1]==y] = tmp;
 63     int d = y->ch[0] == tmp;
 64     if ( y->ch[d^1] = tmp->ch[d] )
 65         tmp->ch[d]->fa = y;
 66     tmp->ch[d] = y;
 67     y->fa = tmp;
 68     y->updata();
 69     tmp->updata();
 70 }
 71 void Splay(SplayNode *tmp, SplayNode *y ) {
 72     while ( tmp->fa != y )    
 73         if ( tmp->fa->fa == y ) Rotate(tmp);
 74         else {
 75             int d1 = tmp->fa->ch[0] == tmp , d2 = tmp->fa->fa->ch[0] == tmp->fa;
 76             if ( d1 == d2 ) Rotate(tmp->fa),Rotate(tmp);
 77             else Rotate(tmp),Rotate(tmp);
 78         }
 79 }
 80 SplayNode* Select(SplayNode* tmp ,int x){
 81     tmp->down();
 82     if ( tmp->ch[0] ){
 83         if ( tmp->ch[0]->size >= x ) return Select( tmp->ch[0] , x );
 84         x -= tmp->ch[0]->size;
 85     }
 86     if ( x == 1 ) return tmp;
 87     return Select( tmp->ch[1] , x-1 );
 88 }
 89 SplayNode* Join(SplayNode* l ,SplayNode* r ){
 90     SplayNode* tmp = l->maxnode();    
 91     Splay( tmp , NULL );
 92     tmp->ch[1] = r; 
 93     r->fa = tmp;
 94     tmp->updata();
 95     return tmp;
 96 }
 97 void    delet( int x ) {
 98     root = Select( root , x );
 99     Splay( root , NULL );
100     root->ch[0]->fa = root->ch[1]->fa = NULL;
101     root = Join( root->ch[0], root->ch[1] );
102 }
103 void    insert(int key ,int x ){
104     root = Select( root,x-1 );
105     Splay( root , NULL );
106     tmp = Select( root , x );
107     Splay( tmp , root );
108     tmp->ch[0] = new SplayNode(key);
109     tmp->ch[0]->fa = tmp;
110     tmp->updata();
111     root->updata();
112 }
113 
114 int        n,m,K1,K2,data[maxn];
115 int        main(){
116     int tt = 0,x;
117     char s[50];
118     while ( ~scanf("%d%d%d%d", &n, &m, &K1, &K2 ) ) {
119         if ( n == 0 && m == 0 && K1 == 0 && K2 == 0 ) break;
120         for (int i = 1; i<=n; i++) scanf("%d", &data[i] );
121         root = build( data , 0 , n+1 );
122         printf("Case #%d:\n" , ++tt );
123         while ( m-- ) {
124             scanf("%s", s );
125             if ( s[0] == 'q' ) {
126                 root = Select( root , 2 );
127                 Splay( root , NULL ); 
128                 printf("%d\n" , root->key );
129             }else 
130             if ( s[0] == 'r' ) {
131                 root = Select(root,1);
132                 Splay( root , NULL );
133                 tmp = Select(root,K1+2);
134                 Splay( tmp , root );
135                 root->ch[1]->ch[0]->rev ^= 1;
136             }else 
137             if ( s[0] == 'i' ) {
138                 scanf("%d", &x );
139                 insert( x , 3 );
140             }else
141             if ( s[0] == 'd' ) delet(2); else
142             if ( s[0] == 'm' ) {
143                 scanf("%d", &x );
144                 if ( x == 1 ) {
145                     tmp = Select(root,root->size-1);
146                     int key = tmp->key;
147                     delet( root->size-1 );
148                     insert( key , 2 );
149                 }
150                 else {
151                     tmp = Select(root,2);
152                     int key = tmp->key;
153                     delet( 2 );
154                     insert( key , root->size );
155                 }
156             }else {
157                 scanf("%d", &x );
158                 root = Select( root , 1 );
159                 Splay( root , NULL );
160                 tmp = Select( root , K2+2 );
161                 Splay( tmp , root );
162                 tmp->ch[0]->add += x;
163                 tmp->ch[0]->key += x;
164             }
165         }
166         root->clear();
167     }
168     return 0;
169 }

转载于:https://www.cnblogs.com/lzqxh/archive/2012/11/20/2778609.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值