HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题

只想到了朴素的n^2做法,然后发现可以用splay维护。于是调了几个小时的splay。。。

splay的元素是从第二个开始的!第一个是之前插入的头节点!

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 
  7 #define Key_value ch[ch[root][1] ][0]
  8 
  9 const int maxn = 5e5+10;
 10 const int INF = 0x3f3f3f3f;
 11 
 12 int pre[maxn],ch[maxn][2],key[maxn],sz[maxn];
 13 int root,tot1;
 14 int rev[maxn],ma[maxn],add[maxn];
 15 int s[maxn],tot2;
 16 int a[maxn];
 17 //int n,q;
 18 
 19 void Treavel(int x)
 20 {
 21     if(x)
 22     {
 23         Treavel(ch[x][0]);
 24         printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d ma=%2d add=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],sz[x],ma[x],add[x]);
 25         Treavel(ch[x][1]);
 26     }
 27 }
 28 void debug()
 29 {
 30     printf("root:%d\n",root);
 31     Treavel(root);
 32 }
 33 //
 34 
 35 void NewNode(int &r,int father,int k)
 36 {
 37     if(tot2) r = s[tot2--];
 38     else r = ++tot1;
 39     pre[r] = father;
 40     ch[r][0] = ch[r][1] = 0;
 41     key[r] = k;
 42     ma[r] = k;
 43     rev[r] = add[r] = 0;
 44     sz[r] = 1;
 45 }
 46 
 47 void Update_add(int r,int c)
 48 {
 49     if(!r) return ;
 50     key[r] += c;
 51     ma[r] += c;
 52     add[r] += c;
 53 }
 54 
 55 void Update_rev(int r)
 56 {
 57     if(!r) return ;
 58     swap(ch[r][0],ch[r][1]);
 59     rev[r] ^= 1;
 60 }
 61 
 62 void push_up(int r)
 63 {
 64     int lson = ch[r][0],rson = ch[r][1];
 65     sz[r] = sz[lson] + sz[rson] + 1;
 66     //ma[r] = max(max(ma[lson],ma[rson]),key[r]);
 67     ma[r] = max(max(ma[lson],ma[rson]),key[r]);
 68 }
 69 void update_same(int r,int c)
 70 {
 71     if(!r) return ;
 72     int lson = ch[r][0],rson = ch[r][1];
 73     key[r] = c;
 74     //ma[r] = max(max(ma[lson],ma[rson]),c);
 75     ma[r] = c;
 76 }
 77 void push_down(int r)
 78 {
 79     if(rev[r])
 80     {
 81         Update_rev(ch[r][0]);
 82         Update_rev(ch[r][1]);
 83         rev[r] = 0;
 84     }
 85     if(add[r])
 86     {
 87         Update_add(ch[r][0],add[r]);
 88         Update_add(ch[r][1],add[r]);
 89         add[r] = 0;
 90     }
 91 }
 92 
 93 void Build(int &x,int l,int r,int father)
 94 {
 95     if(l>r) return ;
 96     int mid = (l+r)>>1;
 97     NewNode(x,father,a[mid]);
 98     Build(ch[x][0],l,mid-1,x);
 99     Build(ch[x][1],mid+1,r,x);
100     push_up(x);
101 }
102 
103 void Init(int x)
104 {
105     root = tot1 = tot2 = 0;
106     ch[root][0] = ch[root][1] = sz[root] = pre[root] = 0;
107     rev[root] = key[root] = 0;
108     ma[root] = 0;
109     NewNode(root,0,-1);
110     NewNode(ch[root][1],root,-1);
111     //for(int i=1;i<=n;i++) scanf("%d",&a[i]);
112     a[1] = x;
113     //n = 1;
114     Build(Key_value,1,1,ch[root][1]);
115     push_up(ch[root][1]);
116     push_up(root);
117 }
118 
119 void Rotate(int x,int kind)
120 {
121     int y = pre[x];
122     push_down(y);
123     push_down(x);
124     ch[y][!kind] = ch[x][kind];
125     pre[ch[x][kind] ] = y;
126     if(pre[y])
127         ch[pre[y] ][ch[pre[y]][1]==y ] = x;
128     pre[x] = pre[y];
129     ch[x][kind] = y;
130     pre[y] = x;
131     push_up(y);
132 }
133 void Splay(int r,int goal)
134 {
135     push_down(r);
136     while(pre[r] != goal)
137     {
138         if(pre[pre[r] ] == goal)
139         {
140             push_down(pre[r]);
141             push_down(r);
142             Rotate(r,ch[pre[r]][0] == r);
143         }
144         else
145         {
146             push_down(pre[pre[r] ]);
147             push_down(pre[r]);
148             push_down(r);
149             int y = pre[r];
150             int kind = ch[pre[y] ][0] == y;
151             if(ch[y][kind] == r)
152             {
153                 Rotate(r,!kind);
154                 Rotate(r,kind);
155             }
156             else
157             {
158                 Rotate(y,kind);
159                 Rotate(r,kind);
160             }
161         }
162         push_up(r);
163         if(goal == 0) root = r;
164     }
165 }
166 
167 int Get_kth(int r,int k)
168 {
169     push_down(r);
170     int t = sz[ch[r][0] ] + 1;
171     if(t == k) return r;
172     if(t > k) return Get_kth(ch[r][0],k);
173     else return Get_kth(ch[r][1],k-t);
174 }
175 
176 void Insert(int pos,int x)
177 {
178     //for(int i=0;i<tot;i++) scanf("%d",&a[i]);
179     int tot = 1;
180     a[0] = x;
181     Splay(Get_kth(root,pos) , 0);
182     Splay(Get_kth(root,pos+1) , root);
183     Build(Key_value,0,tot-1,ch[root][1]);
184     push_up(ch[root][1]);
185     push_up(root);
186 }
187 void erase(int r)
188 {
189     if(!r) return ;
190     s[++tot2] = r;
191     erase(ch[r][0]);
192     erase(ch[r][1]);
193 }
194 void Delete(int pos,int tot)
195 {
196     Splay(Get_kth(root,pos) ,0);
197     Splay(Get_kth(root,pos+tot+1) , root);
198     erase(Key_value);
199     pre[Key_value] = 0;
200     Key_value = 0;
201     push_up(ch[root][1]);
202     push_up(root);
203 }
204 
205 void Reverse(int pos,int tot)
206 {
207     Splay(Get_kth(root,pos) , 0);
208     Splay(Get_kth(root,pos+tot+1), root);
209     Update_rev(Key_value);
210 }
211 
212 void Add(int pos,int tot,int c)
213 {
214     Splay(Get_kth(root,pos) , 0);
215     Splay(Get_kth(root,pos+tot+1) , root);
216     Update_add(Key_value,c);
217     push_up(ch[root][1]);
218     push_up(root);
219 }
220 void Make_same(int pos,int tot,int c)
221 {
222     Splay(Get_kth(root,pos) , 0);
223     Splay(Get_kth(root,pos+tot+1) , root);
224     //printf("tihuan\n");
225     //debug();
226     update_same(Key_value,c);
227     push_up(ch[root][1]);
228     push_up(root);
229 }
230 int Get_max(int pos,int tot)
231 {
232     Splay(Get_kth(root,pos) , 0);
233     Splay(Get_kth(root,pos+tot+1) , root);
234     push_down(root);
235     push_down(ch[root][1]);
236     return ma[Key_value];
237 }
238 int Get_final_ans(int pos,int tot,int x)
239 {
240     int low = pos+1,high = pos+tot-1;
241     int mid;
242     while(low <= high)
243     {
244         mid = (low+high)>>1;
245         int b = key[Get_kth(root,mid)];
246         //printf("mid:%d k:%d\n",mid,b);
247         if(x >= b) low = mid+1;
248         else high = mid -1;
249     }
250     //printf("l:%d h:%d m:%d\n",low,high,mid);
251     return (low+high)>>1;
252 }
253 
254 void Revolve(int l,int r,int t)
255 {
256     if(!t) return ;
257     int c = r - t;
258     Splay(Get_kth(root,l) , 0);
259     Splay(Get_kth(root,c+2),root);
260     int tmp = Key_value;
261     Key_value = 0;
262     push_up(ch[root][1]);
263     push_up(root);
264     Splay(Get_kth(root,r-c+l) , 0);
265     Splay(Get_kth(root,r-c+l+1) , root);
266     Key_value = tmp;
267     pre[Key_value] = ch[root][1];
268     push_up(ch[root][1]);
269     push_up(root);
270 }
271 
272 int save[maxn];
273 int T,N;
274 int LL,RR;
275 int DP(int l,int n)
276 {
277     if(n==0) return 0;
278     int i,len=1,pos;
279     Init(save[l]);
280     //debug();
281     //printf("---\n");
282     for(int i=l+1;i<=n;i++)
283     {
284         //printf("save:%d len:%d max:%d\n",save[i],len,Get_max(1,len));
285         if(save[i] == 0)
286         {
287             Add(1,len,1);
288             Insert(1,0);
289             len++;
290         }
291         else if(save[i] > Get_max(1,len))
292         {
293             //printf("max:%d\n",Get_max(1,len));
294             Insert(len+1,save[i]);
295             len++;
296         }
297         else{
298             pos = Get_final_ans(1,len,save[i]);
299             //printf("pos:%d\n",pos);
300             //Add(pos,1,save[i]-key[Get_kth(root,pos)]);
301             Make_same(pos,1,save[i]);
302         }
303 
304         //debug();
305         //printf("---\n");
306     }
307     return len;
308 }
309 bool flag = false;
310 void deal()
311 {
312     int i = 1;
313     while( save[i]==0 && i <= N) i++;
314     LL = i;
315     i = N;
316     if(LL>=N ) {flag = true;return;}
317     while(save[i] == 0 && i >= 0) i--;
318     RR = i;
319 }
320 int main()
321 {
322     //freopen("input","r",stdin);
323     //freopen("splay.out","w",stdout);
324     scanf("%d",&T);
325     for(int cas=1;cas<=T;cas++)
326     {
327         scanf("%d",&N);
328         for(int i=1;i<=N;i++)
329         {
330             scanf("%d",&save[i]);
331         }
332         flag = false;
333         deal();
334         if(flag){
335             printf("Case #%d: %d\n",cas,N);
336             continue;
337         }
338         //printf("LL:%d RR:%d\n",LL,RR);
339         int ans = DP(LL,RR);
340         printf("Case #%d: %d\n",cas,ans+LL-1+(N-RR));
341     }
342 }
343 /*
344 int m;
345 int main()
346 {
347     while(~scanf("%d ",&n))
348     {
349         Init();
350         //debug();
351         scanf("%d ",&m);
352         char op[10];
353         for(int i=0;i<m;i++)
354         {
355             scanf(" %s",op);
356             //printf("i:%d op:%s\n",i,op);
357             int x,y,c,t;
358             if(op[0] == 'A')            //add
359             {
360                 scanf("%d%d%d",&x,&y,&c);
361                 Add(x,y-x+1,c);
362             }
363             else if(op[0] == 'I')       //insert
364             {
365                 scanf("%d",&x);
366                 Insert(x,1);
367             }
368             else if(op[0] == 'D')       //delete
369             {
370                 scanf("%d",&x);
371                 Delete(x,1);
372             }
373             else if(op[0] == 'M')       //min
374             {
375                 scanf("%d%d",&x,&y);
376                 printf("%d\n",Get_min(x,y-x+1));
377             }
378             else if(op[0] == 'R' && op[3] == 'E')//reverse
379             {
380                 scanf("%d%d",&x,&y);
381                 Reverse(x,y-x+1);
382             }
383             else                        //revolve
384             {
385                 scanf("%d%d%d",&x,&y,&t);
386                 t = (t%(y-x+1)+(y-x+1))%(y-x+1);
387                 Revolve(x,y,t);
388             }
389             //debug();
390         }
391     }
392 }
393 */

 

posted @ 2016-07-30 13:35  Helica  阅读(222)  评论(0编辑  收藏  举报