BZOJ1503 郁闷的出纳员

BZOJ 1503 郁闷的出纳员


解析:题目不难, 算是Splay区间操作入门题, 主要就是考虑每次减薪操作时, 直接将当前的薪水小于min限制的人员全部删掉即可, 加薪的时候直接在root处打上tag 然后在合适的时候进行pushdown即可, 注意select单个node的时候, 一定样pushdown(),不然会WA.


Source:

#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
        
        
#include
        
        
          #include 
         
           #include 
          
            using namespace std; inline void R(int &v) { char c=0; bool p=true; v=0; while(!isdigit(c)) { if(c=='-') p=false; c=getchar(); } while(isdigit(c)) { v=(v<<3)+(v<<1)+(c^'0'); c=getchar(); } if(!p) v=-v; } const int MAXN=1e6; const int INF=~0u>>1; template 
           
             struct memorypool { T buf[size], *tail, *st[size]; int top; inline T *alloc() { return top ? st[--top] : tail++; } inline void recycle(T *x) { st[top++] = x; } memorypool() : top(0), tail(buf) {} }; template 
            
              struct Splay { enum Relation { L = 0, R = 1 }; struct node { node *child[2], *parent, **root; T value, lazy; int size, count; inline void init(node *parent, node **root, const T &value) { this->parent = parent, this->value = value, this->root = root; this->count = this->size = 1, this->lazy = 0, child[L] = child[R] = NULL; } // inline Relation relation() { return this == parent->child[L] ? L : R; } inline void recycle(memorypool 
             
               &pool) { if (child[L]) pool.recycle(child[L]); if (child[R]) pool.recycle(child[R]); } inline void updata(const T &delta) { if (this->value != INF && this->value != -INF) this->value += delta; this->lazy += delta; } inline void pushdown() { if (lazy) { if (child[L]) child[L]->updata(lazy); if (child[R]) child[R]->updata(lazy); lazy = 0; } } inline Relation relation() { return this == parent->child[L] ? L : R; } inline void maintain() { pushdown(), size = count + (child[L] ? child[L]->size : 0) + (child[R] ? child[R]->size : 0); } inline void rotate() { pushdown(); Relation x = relation(); node *oldParent = parent; if (oldParent->parent) oldParent->parent->child[oldParent->relation()] = this; parent = oldParent->parent, oldParent->child[x] = child[x ^ 1]; if (child[x ^ 1]) child[x ^ 1]->parent = oldParent; child[x ^ 1] = oldParent, oldParent->parent = this, oldParent->maintain(), maintain(); if (!parent) *root = this; } inline void splay(node *targetParent = NULL) { while (parent != targetParent) { parent->pushdown(), pushdown(); if (parent->parent == targetParent) rotate(); else { parent->parent->pushdown(); if (parent->relation() == relation()) parent->rotate(), rotate(); else rotate(), rotate(); } } } inline node *precursor() { splay(); node *v = child[L]; while (v->child[R]) v = v->child[R]; return v; } inline node *successor() { splay(); node *v = child[R]; while (v->child[L]) v = v->child[L]; return v; } inline int rank() { return child[L] ? child[L]->size : 0; } } *root; memorypool 
              
                pool; Splay() : root(NULL) { insert(INF), insert(-INF); } inline node *find(const T &value) { node *v = root; while (v && value != v->value) v->pushdown(), v = (value < v->value ? v->child[L] : v->child[R]); return v ? (v->splay(), v) : NULL; } inline node *insert(const T &value) { node *v = find(value); if (v) return v->count++, v->maintain(), v; node **target = &root, *parent = NULL; while (*target) parent = *target, parent->pushdown(), parent->size++, target = (value < parent->value ? &parent->child[L] : &parent->child[R]); return *target = pool.alloc(), (*target)->init(parent, &root, value), (*target)->splay(), root; } inline int rank(const T &value) { node *v=find(value); if(v) return v->rank(); else { node *v=insert(value); register int ans=v->rank(); return erase(v), ans; } } inline const T &precursor(const T &value) { node *v=find(value); if(v) return v->precursor()->value; else { node *v=insert(value); const T &ans=v->precursor()->value; return erase(v), ans; } } inline const T &successor(const T &value) { node *v=find(value); if(v) return v->successor()->value; else { node *v=insert(value); const T &ans=v->successor()->value; return erase(v), ans; } } inline void updata(const T &value) { root->updata(value); } inline const T &select(int k) { k++; node *v = root; while (v->pushdown(), !(v->rank() < k && v->rank() + v->count >= k)) v = (k <= v->rank() ? v->child[L] : (k -= v->rank() + v->count, v->child[R])); return v->splay(), v->value; } inline void erase(node *l, node *r) { node *pre = l->precursor(), *suc = r->successor(); pre->splay(), suc->splay(pre), suc->child[L]->recycle(pool); pool.recycle(suc->child[L]), suc->child[L] = NULL, suc->maintain(), pre->maintain(); } inline void erase(node *v) { v->count > 1 ? v->count-- : erase(v, v); } inline void erase(const T &l, const T &r) { node *vl = find(l), *vr = find(r); if (!vl) vl = insert(l); if (!vr) vr = insert(r); erase(vl, vr); } inline int size() { return root->size - 2; } }; Splay 
               
                 splay; int main() { int n,min,x,ans,cnt=0; char c[10]; R(n),R(min); while(n--) { scanf("%s",c),R(x); if(c[0]=='I') { if(x>=min) { splay.insert(x); cnt++; } } else if(c[0]=='A') splay.updata(x); else if(c[0]=='S') splay.updata(-x),splay.erase(-INF+1,min-1); else if(c[0]=='F') { splay.erase(-INF+1,min-1); if(x>splay.size()) cout<<"-1"<<'\n'; else cout< 
                
                  <<'\n'; } } cout< 
                  
                 
                
               
              
             
            
           
          
        
       
       
      
      
     
     
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值