zoukankan      html  css  js  c++  java
  • BZOJ 3506 机械排序臂 splay

        这是宝宝第二次敲splay了(如果LCT不算的话),还好吧!为什么自己写的TLE了呢?找个时间写下对拍吧!暂时还是要学习别人的代码的。一开始的思路是找到最小的点后,返回距离,然后删掉。在这里更深刻地体会到了自己的天真无邪,too young too simple , (假设当前的根是我们要删除的)以为只要把左子节点的父亲修改为右子结点, 右子结点的左儿子设成左子结点,然后把右子结点更新为根就好。(有没有发现问题所在?,右子结点原来的左儿子怎么办?)那好问题出现了就要寻求解决的方法了,我是这样想的,在右子树里一直往左走,走到第一个没有左子结点的位置,返回其标号,然后我们再把它旋转到根,然后……(你懂的)。然而这个TLE了。 其实这还不是我最开始的我,最开始的我是这样的,弄了左右边界,然后发现边界都被我翻转了,(有没有感到我的愚蠢)。后来再次Orz了黄学长的代码,当然我自己是做了修改的。加油了。splay还是很重要的。(我不想做源程狗。)

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #define lc c[k][0]
      5 #define rc c[k][1]
      6 #define rep(i,j,k) for(int  i = j;  i <= k; i++) 
      7 #define maxn 100233
      8 using namespace std;
      9 
     10 struct node{
     11 int v, pos;
     12 bool operator < (const node&rhs) const{
     13     return pos < rhs.pos;
     14 }
     15 } nod[maxn];
     16 
     17 bool cmp(node a,node b)
     18 {
     19     return a.v < b.v || (a.v == b.v && a.pos < b.pos ); 
     20 }
     21 
     22 int read()
     23 {
     24     int s = 0, t = 1; char c = getchar();
     25     while( !isdigit(c) ){
     26         if( c == '-' )  t= -1; c = getchar();
     27     }
     28     while( isdigit(c) ){
     29         s =s * 10 + c - '0'; c= getchar();
     30     }
     31     return s * t;
     32 }
     33 
     34 int s[maxn], pa[maxn], c[maxn][2], mn[maxn], v[maxn], root;
     35 bool rev[maxn];
     36 
     37 void pushdown(int k)
     38 {
     39     if( rev[k] ){
     40         rev[k] ^= 1, rev[lc] ^= 1, rev[rc] ^= 1;
     41         swap(lc,rc);
     42     } 
     43 }
     44 
     45 void maintain(int k)
     46 {
     47     mn[k] = k;
     48     if( v[mn[lc]] < v[mn[k]] ) mn[k] = mn[lc];
     49     if( v[mn[rc]] < v[mn[k]] ) mn[k] = mn[rc];
     50     s[k] = s[lc] + s[rc] + 1; 
     51 }
     52 
     53 void rorate(int k,int &root)
     54 {
     55     int fa = pa[k], gfa = pa[fa];
     56     int l = c[fa][1] == k, r = l ^ 1;
     57     if( fa != root ){
     58         c[gfa][c[gfa][1] == fa] = k;
     59     } else root = k;
     60     pa[fa] = k, pa[c[k][r]] = fa, pa[k] = gfa;
     61     c[fa][l] = c[k][r], c[k][r] = fa; maintain(fa), maintain(k);
     62 }
     63 
     64 int q[maxn];
     65 void splay(int k,int &root)
     66 {
     67     int top = 0; q[++top] = k;
     68     for(int x = k; x != root; x = pa[x] ) q[++top] = pa[x];
     69     while( top ) pushdown(q[top--]);
     70     while( k != root ){
     71         int fa = pa[k], gfa = pa[fa];
     72         if( fa != root ) {
     73             if( c[gfa][1] == fa ^ c[fa][1] == k ) rorate(k,root);
     74             else rorate(fa,root);
     75         }
     76         rorate(k,root);
     77     }
     78 }
     79 
     80 void build(int l,int r,int pre)
     81 {
     82     if( l > r ) return;
     83     int mid = (l+r)>>1;
     84     c[pre][pre < mid] = mid; pa[mid] = pre; v[mid] = nod[mid].v, mn[mid] = mid;
     85     c[mid][0] = c[mid][1] = 0;
     86     if( l < r ){
     87         build(l,mid-1,mid); build(mid+1,r,mid);
     88         maintain(mid);
     89     } else s[mid] = 1;
     90 }
     91 
     92 int rank(int x,int k)
     93 {
     94     if( rev[k] ) pushdown(k);
     95     if( s[lc] >= x ) return rank(x,lc);
     96     else if( s[lc] + 1 < x ) return rank(x-s[lc]-1,rc);
     97     else return k;
     98 }
     99 
    100 int query_min(int x,int y)
    101 {
    102     x = rank(x,root), y = rank(y+2,root);
    103     splay(x,root); splay(y,c[x][1]);
    104     return mn[c[y][0]]; 
    105 }
    106 
    107 void rever(int x,int y)
    108 {
    109     x = rank(x,root), y = rank(y+2,root);
    110     splay(x,root); splay(y,c[x][1]);
    111     rev[c[y][0]] ^= 1;
    112 }
    113 
    114 void out(int k)
    115 {
    116     if( lc ) out(lc);
    117     cout<<v[k]<<endl;
    118     if( rc ) out(rc);
    119 }
    120 
    121 int main()
    122 {
    123     int n;
    124     while( scanf("%d", &n) && n ){
    125     v[0] = nod[1].v = nod[n+2].v = 0x7fffffff;
    126     rep(i,2,n+1) nod[i].v = read(), nod[i].pos = i;
    127     sort(nod+2,nod+2+n,cmp); root = (3+n)>>1;
    128     rep(i,2,n+1) nod[i].v = i-1;
    129     sort(nod+2,nod+2+n);  build(1,n+2,0);  //out(root);
    130     rep(i,1,n){
    131         int q = query_min(i,n); splay(q,root);
    132         printf("%d ", s[c[q][0]] );
    133         rever(i,s[c[q][0]]);
    134     }
    135             puts("");
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    线程,协程
    python魔法方法详解
    Sorted方法排序用法
    time模块
    Haroopad安装与配置: Linux系统下最好用的Markdown编辑器
    C++ Primer第五版答案
    Ubuntu14.04安装有道词典(openyoudao)
    Ubuntu14.04下Sublime Text 3解决无法输入中文
    OpenLTE安装教程
    GNU Radio: Overview of the GNU Radio Scheduler
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5124127.html
Copyright © 2011-2022 走看看