• Bzoj1503--Noi2004郁闷的出纳员


    treap乱搞一下

    对于工资的加减不直接修改的点的值或打标记,而是维护一个外围的delta,这样维护也很方便

    剩下删除和插入都是基本操作了

    另: linux下rand()的返回值是1-2^31-1,虽然感觉没什么关系,交上去就会被卡T掉。。。取个模就过了

    代码:

    #include<bits/stdc++.h>
    #define MAXN 100205
    #define MAXM 3005
    #define INF 1000000000
    #define MOD 998244353
    #define LL long long
    using namespace std;
    
    inline int read() {
        int ret=0,f=1;char c=getchar();
        while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
        while(c<='9'&&c>='0') {ret=ret*10+c-'0';c=getchar();}
        return ret*f;
    }
    
    int n,m,delta;
    
    struct node{
        int son[2],s,v,r,par,sz;
    }x[MAXN];
    struct Treap{
        int L,R,root,away,cnt;
        void init() {
            L=0;R=1;root=MAXN-5;away=0;cnt=0;
            x[MAXN-5].r=INF;x[MAXN-5].v=INF;
        }
        
        inline void rotate(int num,int p) {
            int pa=x[num].par,t=x[num].sz;
            x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num;
            x[num].sz=x[pa].sz;x[pa].sz-=t-x[x[num].son[p]].sz;
            x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) {x[x[num].son[p]].par=pa;}
            x[num].son[p]=pa;x[num].par=x[pa].par;x[pa].par=num;
        }
        
        void Insert(int v) {
            x[++cnt].v=v;x[cnt].r=rand()%1000007;x[cnt].s=1;x[cnt].sz=1;
            int now=root,pre;
            while(true) {
                if(v==x[now].v) {x[now].s++;x[now].sz++;cnt--;return;}
                pre=v<x[now].v?R:L;x[now].sz++;
                if(!x[now].son[pre]) {x[now].son[pre]=cnt;x[cnt].par=now;break;}
                now=x[now].son[pre];
            }
            now=cnt;
            while(true) {
                if(x[x[now].par].son[L]==now) pre=R;else pre=L;
                if(x[now].r>x[x[now].par].r) rotate(now,pre);
                else break;
            }
        }
        void Del(int num) {
            while(x[num].son[L]) rotate(x[num].son[L],R);
            int now=x[num].par,pre=x[x[num].par].son[L]==num?L:R;
            while(now) {x[now].sz-=x[num].sz;now=x[now].par;}
            away+=x[num].sz;x[x[num].par].son[pre]=0;
        }
        void Check(int v) {
            int now=root,ed;
            while(true) {
                while(x[now].son[R]) now=x[now].son[R];
                if(x[now].v<v) Del(now);
                else break;
                now=root;
            }
        }
        int Qurey(int k) {
            int now=root;
            if(k>x[root].sz) return -1;
            while(true) {
                if(x[x[now].son[L]].sz>=k-x[now].s&&x[x[now].son[L]].sz<k) return x[now].v;
                if(x[x[now].son[L]].sz<k) {k-=x[now].s+x[x[now].son[L]].sz;now=x[now].son[R];}
                else now=x[now].son[L];
                
            }
        }
        
        int Finish() {return away;}
    };
    
    int main() {
        srand(2333333);
        n=read();m=read();
        Treap p;char q[10];int k,ret;
        p.init();
        for(int i=1;i<=n;i++) {
            scanf("%s",q);k=read();
            if(q[0]=='I') if(k>=m) p.Insert(k+delta);
            if(q[0]=='A') delta-=k;
            if(q[0]=='S') {delta+=k;p.Check(m+delta);}
            if(q[0]=='F') {
                ret=p.Qurey(k);
                printf("%d
    ",ret-(ret==-1?0:delta));
            }
        }
        printf("%d
    ",p.Finish());
        return 0;
    }
  • 相关阅读:
    JavaWeb学习笔记(3)
    JavaWeb学习笔记(2)
    JavaWeb学习笔记(1)
    Java学习笔记(20)
    Java学习笔记(19)
    Java学习笔记(18)
    Java学习笔记(17)
    Java学习笔记(16)
    Java学习笔记(15)
    Java学习笔记(14)
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5915078.html
Copyright © 2020-2023  润新知