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 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4760544.html