zoukankan      html  css  js  c++  java
  • poj 3580 splay

    维修数列的简化版,要求的操作还是挺多的,运行时间大概1s。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 
      6 const int N = 100002;
      7 int v[N];
      8 int n, m;
      9 
     10 struct Node 
     11 {
     12     Node * ch[2];
     13     int rank;
     14     int sz;
     15     int val;
     16     int minn;
     17     int add;
     18     int flip;
     19 
     20     int cmp( int x ) const 
     21     {
     22         if ( x == rank ) return -1;
     23         return x < rank ? 0 : 1;
     24     }
     25 
     26     void pushdown()
     27     {
     28         if ( add )
     29         {
     30             if ( ch[0] != NULL )
     31             {
     32                 ch[0]->val += add;
     33                 ch[0]->minn += add;
     34                 ch[0]->add += add;
     35             }
     36             if ( ch[1] != NULL )
     37             {
     38                 ch[1]->val += add;
     39                 ch[1]->minn += add;
     40                 ch[1]->add += add;
     41             }
     42             add = 0;
     43         }
     44         if ( flip )
     45         {
     46             swap( ch[0], ch[1] );
     47             flip = 0;
     48             if ( ch[0] != NULL )
     49             {
     50                 ch[0]->flip ^= 1;
     51             }
     52             if ( ch[1] != NULL )
     53             {
     54                 ch[1]->flip ^= 1;
     55             }
     56         }
     57     }
     58 
     59     void maintain()
     60     {
     61         sz = rank = 1;
     62         minn = val;
     63         if ( ch[0] != NULL )
     64         {
     65             sz += ch[0]->sz;
     66             rank += ch[0]->sz;
     67             minn = min( minn, ch[0]->minn );
     68         }
     69         if ( ch[1] != NULL )
     70         {
     71             sz += ch[1]->sz;
     72             minn = min( minn, ch[1]->minn );
     73         }
     74     }
     75 } * root;
     76 
     77 void rotate( Node * & o, int d )
     78 {
     79     Node * k = o->ch[d ^ 1];
     80     o->ch[d ^ 1] = k->ch[d];
     81     k->ch[d] = o;
     82     o->maintain();
     83     k->maintain();
     84     o = k;
     85 }
     86 
     87 void splay( Node * & o, int k )
     88 {
     89     o->pushdown();
     90     o->maintain();
     91     int d = o->cmp(k);
     92     if ( d != -1 )
     93     {
     94         if ( d == 1 ) k -= o->rank;
     95         Node * p = o->ch[d];
     96         p->pushdown();
     97         p->maintain();
     98         int d2 = p->cmp(k);
     99         if ( d2 != -1 )
    100         {
    101             int k2 = ( d2 == 0 ? k : k - p->rank ); 
    102             splay( p->ch[d2], k2 );
    103             if ( d == d2 )
    104             {
    105                 rotate( o, d ^ 1 );
    106             }
    107             else
    108             {
    109                 rotate( o->ch[d], d );
    110             }
    111         }
    112         rotate( o, d ^ 1 );
    113     }
    114 }
    115 
    116 Node * build( int l, int r )
    117 {
    118     if ( l > r ) return NULL;
    119     Node * o = new Node();
    120     int mid = ( l + r ) >> 1;
    121     o->sz = r - l + 1;
    122     o->val = o->minn = v[mid];
    123     o->rank = mid - l + 1;
    124     o->ch[0] = build( l, mid - 1 );
    125     o->ch[1] = build( mid + 1, r );
    126     o->maintain();
    127     return o;
    128 }
    129 
    130 void setRange( int l, int r )
    131 {
    132     splay( root, l );
    133     splay( root->ch[1], r - l + 2 );
    134 }
    135 
    136 void add( int l, int r, int d )
    137 {
    138     setRange( l, r );
    139     root->ch[1]->ch[0]->val += d;
    140     root->ch[1]->ch[0]->minn += d;
    141     root->ch[1]->ch[0]->add += d;
    142 }
    143 
    144 void reverse( int l, int r )
    145 {
    146     setRange( l, r );
    147     root->ch[1]->ch[0]->flip ^= 1;
    148 }
    149 
    150 void revolve( int l, int r, int d )
    151 {
    152     reverse( l, r - d );
    153     reverse( r - d + 1, r );
    154     reverse( l, r );
    155 }
    156 
    157 void insert( int k, int vv )
    158 {
    159     k++;
    160     splay( root, k );
    161     splay( root->ch[1], 1 );
    162     Node * & o = root->ch[1]->ch[0];
    163     o = new Node();
    164     o->sz = o->rank = 1;
    165     o->val = o->minn = vv;
    166     o->add = o->flip = 0;
    167     root->ch[1]->maintain();
    168     root->maintain();
    169 }
    170 
    171 void remove( int k )
    172 {
    173     splay( root, k );
    174     splay( root->ch[1], 2 );
    175     root->ch[1]->ch[0] = NULL;
    176     root->ch[1]->maintain();
    177     root->maintain();
    178 }
    179 
    180 inline int query( int l, int r )
    181 {
    182     setRange( l, r );
    183     return root->ch[1]->ch[0]->minn;
    184 }
    185 
    186 int main ()
    187 {
    188     while ( scanf("%d", &n) != EOF )
    189     {
    190         for ( int i = 1; i <= n; i++ )
    191         {
    192             scanf("%d", v + i);
    193         }
    194         root = build( 0, n + 1 );
    195         char cmd[11];
    196         int a, b, c;
    197         scanf("%d", &m);
    198         while ( m-- )
    199         {
    200             scanf("%s", cmd);
    201             if ( cmd[0] == 'A' )
    202             {
    203                 scanf("%d%d%d", &a, &b, &c);
    204                 add( a, b, c );
    205             }
    206             else if ( cmd[0] == 'R' )
    207             {
    208                 if ( cmd[3] == 'E' )
    209                 {
    210                     scanf("%d%d", &a, &b);
    211                     reverse( a, b );
    212                 }
    213                 else if ( cmd[3] == 'O' )
    214                 {
    215                     scanf("%d%d%d", &a, &b, &c);
    216                     c = c % ( b - a + 1 );
    217                     if ( !c ) continue;
    218                     revolve( a, b, c );
    219                 }
    220             }
    221             else if ( cmd[0] == 'I' )
    222             {
    223                 scanf("%d%d", &a, &b);
    224                 insert( a, b );
    225             }
    226             else if ( cmd[0] == 'D' )
    227             {
    228                 scanf("%d", &a);
    229                 remove(a);
    230             }
    231             else 
    232             {
    233                 scanf("%d%d", &a, &b);
    234                 printf("%d
    ", query( a, b ));
    235             }
    236         }
    237     }
    238     return 0;
    239 }
  • 相关阅读:
    解决子元素浮动,父元素高度变小的问题
    解决子元素设置margintop,效果到父元素上的问题
    应用部署时自动推送企业微信提醒
    自定义Gradle Task实现一键批量部署Springboot应用
    springboot中@PostConstruct、CommandLineRunner、BeanPostProcessor执行顺序
    win7 关闭防火墙
    Android 4.1模拟器访问服务器接口
    Android开发教程 葵花宝典第一层 初识Android
    Android开发教程 葵花宝典第四层 控件之 Toast Spinner RadioButton
    Android开发教程 葵花宝典第三层 控件之 Button CheckBox EditText TextView
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4760544.html
Copyright © 2011-2022 走看看