zoukankan      html  css  js  c++  java
  • bzoj1503 Splay 维护名次数,支持删除

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

    题解:

    维护一颗Splay和一个外部变量,树中每个节点表示一个人,节点权值a + 外部变量delta = 该员工工资。

    细节看代码。

    注意:一进来工资就低于最低工资的人不能算是“离开公司”的人。

      1 #include <cstdio>
      2 #define fprintf(...)
      3 #define maxn 100100
      4 
      5 struct Splay {
      6     int key[maxn], pre[maxn], son[maxn][2], siz[maxn], ntot, root;
      7     int trash[maxn], rtot;
      8 
      9     Splay():ntot(0),root(0),rtot(0){}
     10     void update( int nd ) {
     11         siz[nd] = siz[son[nd][0]] + siz[son[nd][1]] + 1;
     12     }
     13     void rotate( int nd, int d ) {
     14         int p = pre[nd];
     15         int s = son[nd][!d];
     16         int ss = son[s][d];
     17 
     18         if( p ) son[p][ nd==son[p][1] ] = s;
     19         else root = s;
     20         son[nd][!d] = ss;
     21         son[s][d] = nd;
     22 
     23         if( ss ) pre[ss] = nd;
     24         pre[nd] = s;
     25         pre[s] = p;
     26 
     27         update( nd );
     28         update( s );
     29     }
     30     void splay( int nd, int top=0 ) {
     31         while( pre[nd]!=top ) {
     32             int p = pre[nd];
     33             int nl = nd==son[p][0];
     34             if( pre[p]==top ) {
     35                 rotate( p, nl );
     36             } else {
     37                 int pp = pre[p];
     38                 int pl = p==son[pp][0];
     39                 if( nl==pl ) {
     40                     rotate( pp, pl );
     41                     rotate( p, nl );
     42                 } else {
     43                     rotate( p, nl );
     44                     rotate( pp, pl );
     45                 }
     46             }
     47         }
     48     }
     49     int newnode( int k, int p ) {
     50         int nd;
     51         if( rtot ) nd = trash[rtot--];
     52         else nd = ++ntot;
     53         key[nd] = k;
     54         pre[nd] = p;
     55         son[nd][0] = son[nd][1] = 0;
     56         siz[nd] = 1;
     57         return nd;
     58     }
     59     void insert( int k ) {
     60         fprintf( stderr, "insert(%d)
    ", k );
     61         if( !root ) {
     62             root = newnode( k, 0 );
     63             return;
     64         }
     65         int nd = root;
     66         while( son[nd][ k<key[nd] ] ) 
     67             nd = son[nd][ k<key[nd] ];
     68         son[nd][ k<key[nd] ] = newnode( k, nd );
     69         update( nd );
     70         splay( nd, 0 );
     71     }
     72     void erase_subtree( int nd ) {
     73         fprintf( stderr, "erase_subtree(%d)
    ", nd );
     74         if( !nd ) return;
     75         erase_subtree( son[nd][0] );
     76         erase_subtree( son[nd][1] );
     77         trash[++rtot] = nd;
     78     }
     79     void erase( int k ) {
     80         fprintf( stderr, "erase(%d)
    ", k );
     81         int nd = root;
     82         int active = nd;
     83         while( nd ) {
     84             if( key[nd]<=k ) {
     85                 int p = pre[nd];
     86                 int ls= son[nd][0];
     87 
     88                 if( p ) son[p][ nd==son[p][1] ] = son[nd][0];
     89                 else root = son[nd][0];
     90                 pre[son[nd][0]] = p;
     91                 
     92                 pre[nd] = 0;
     93                 son[nd][0] = 0;
     94 
     95                 erase_subtree( nd );
     96                 
     97                 if( p ) update( p );
     98                 nd = ls;
     99             } else {
    100                 active = nd;
    101                 nd = son[nd][1];
    102             }
    103         }
    104         splay(active);
    105     }
    106     int nth( int n ) {
    107         fprintf( stderr, "nth(%d)
    ", n );
    108         int nd = root;
    109         while(1) {
    110             int ls = siz[son[nd][0]];
    111             if( n<=ls ) {
    112                 nd=son[nd][0];
    113             } else if( n>=ls+2 ) {
    114                 nd=son[nd][1];
    115                 n -= ls+1;
    116             } else
    117                 break;
    118         }
    119         splay( nd );
    120         return key[nd];
    121     }
    122     void print( int nd ) {
    123         if(!nd) return;
    124         print( son[nd][0] );
    125         fprintf( stderr, "%d %d %d %d %d
    ", nd, pre[nd], son[nd][0], son[nd][1],
    126                 key[nd] );
    127         print( son[nd][1] );
    128     }
    129 };
    130 
    131 Splay T;
    132 int n, delta, limit, cnt;
    133 
    134 int main() {
    135     //freopen( "input", "r", stdin );
    136     scanf( "%d%d", &n, &limit );
    137     delta = 0;
    138     cnt = 0;
    139     while(n--) {
    140         char ch[2];
    141         int k;
    142         scanf( "%s%d", ch, &k );
    143         switch(ch[0]) {
    144             case 'I':
    145                 if( k<limit ) break;
    146                 cnt++;
    147                 k -= delta;
    148                 T.insert( k );
    149                 break;
    150             case 'A':
    151                 delta += k;
    152                 break;
    153             case 'S':
    154                 delta -= k;
    155                 T.erase( limit-delta-1 );
    156                 break;
    157             case 'F':
    158                 if( !(1<=k && k<=T.siz[T.root]) ) printf( "-1
    " );
    159                 else printf( "%d
    ", T.nth(k)+delta );
    160                 break;
    161         }
    162         fprintf( stderr, "delta=%d
    ", delta );
    163         //T.print( T.root );
    164         fprintf( stderr, "
    " );
    165     }
    166     printf( "%d
    ", cnt-T.siz[T.root] );
    167 }
    View Code
  • 相关阅读:
    MySQL -- 表联结
    Unittest方法 -- 项目实现自动发送邮件
    Linux工作中常用命令
    Requests方法 -- Token获取操作
    Requests方法 -- 关联用例执行
    Requests方法 -- Blog流程类进行关联
    Requests方法 -- 参数化
    defer和async的区别
    js函数收藏:获取cookie值
    XSHELL使用技巧总结
  • 原文地址:https://www.cnblogs.com/idy002/p/4273608.html
Copyright © 2011-2022 走看看