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\n",ret-(ret==-1?0:delta));
        }
    }
    printf("%d\n",p.Finish());
    return 0;
}
时间: 2024-10-06 01:14:51

Bzoj1503--Noi2004郁闷的出纳员的相关文章

bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 8705  Solved: 3027[Submit][Status][Discuss] Description OIER 公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是, 我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反

[BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量.我真不知道除了调工资他还做什么其它事情.工资的频繁调

[BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)

Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量.我真不知道除了调工资他还做什么其它事情.工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司

BZOJ1503 [NOI2004]郁闷的出纳员

AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 [我的感受] 这题郁闷了很久,因为discuss里讨论的问题和我都不是一个问题... discuss里的当然是一大坑点啦,就是初始工资挂了的不算在最后踢出的人数中. 不过这个我倒是刚开始就这么打的...不过我一直超时啊超时啊... 终于要来了数据...额,原来是平衡树的性质都没怎么用...根本没转几次啊,然后数据就特意卡了这个,连续添加递增工资的人[变成了链] 那我就随机转一转好了

bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版

这道题写法和之前差不多 但是fhqtreap在加点的时候为了同时维护大根堆以及二叉排序树的性质所以插入时也要注意分裂 fhqteap需要判断指针是否为空 不然就会re 这个我调了很久 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=150000; int read(){ int ans=0,f=1,c=getchar(); while(c<

BZOJ1503 NOI2004 郁闷的出纳员 平衡树

题意:开始时给定一个空的数列,要求维护:1.加入一个数  2.数列中所有元素+k  3.数列中所有元素-k  4.查询数列中的第k大.其中对于任意时刻,如果有一个元素<Min,则删除该元素. 题解:平衡树裸题……话说当年还打算把Splay Treap SBT都学一下,结果现在只会Splay了QAQ #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #in

【权值分块】bzoj1503 [NOI2004]郁闷的出纳员

权值分块,离散化非常蛋疼,只能离散化搞…… 需要支持操作:删除<=某个值得所有权值==打标记 O(sqrt(n)) 码长和我的平衡树差不多……速度快3倍左右. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 #define N 201001 7 struct Point{int v,p;}tmp

1503: [NOI2004]郁闷的出纳员 Treap

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 6263  Solved: 2190[Submit][Status] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可

[BZOJ 1503] [NOI2004] 郁闷的出纳员

1503: [NOI2004] 郁闷的出纳员 Time Limit: 5 SecMemory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量.我真不知道除了调工资他还做什么其它事情.工资的频繁调整

BZOJ 题目1503: [NOI2004]郁闷的出纳员(SBT+延迟操作)

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 8058  Solved: 2828 [Submit][Status][Discuss] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反