BZOJ1503: [NOI2004]郁闷的出纳员

来源:互联网 发布:怎么进入淘宝图片空间 编辑:程序博客网 时间:2024/06/01 08:10

题目链接

全部修改代价太大,就记录每个员工工资变化量Delta,新加入时当前员工的工资若>=min,就加入新点,值为工资x-Delta。

(立刻离开的都不算入最后的答案,坑爸爸!)

【代码】

#include <cstdio>#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#define N 100005 #define M 200005#define INF 1e9+1using namespace std;typedef long long ll;typedef pair<ll,ll> pa;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,Delta,rt,cnt,ans,mn;int son[N][2],fa[N],num[N],sz[N];void pushup(int p){    sz[p]=sz[son[p][0]]+sz[son[p][1]]+1;}void Rotate(int x,int &k){    int y=fa[x],z=fa[y],r,l;    l=(son[y][0]!=x);r=l^1;    if(y==k) k=x;    else son[z][son[z][0]!=y]=x;    fa[x]=z;fa[y]=x;fa[son[x][r]]=y;    son[y][l]=son[x][r];son[x][r]=y;    pushup(y);pushup(x);}void Splay(int x,int &k){    while(x!=k)    {        int y=fa[x],z=fa[y];        if(y!=k)        {            if((son[z][0]==y)^(son[y][0]==x)) Rotate(x,k);            else Rotate(y,k);        }        Rotate(x,k);    }}void Insert(int &k,int x,int Last){    if(!k)    {        k=++cnt;fa[k]=Last;sz[k]=1;        num[k]=x;Splay(k,rt);        return;    }    if(x<num[k]) Insert(son[k][0],x,k);    else Insert(son[k][1],x,k);}int Find(int k,int x){    if(sz[son[k][1]]+1==x) return k;    if(sz[son[k][1]]+1>x) return Find(son[k][1],x);    return Find(son[k][0],x-sz[son[k][1]]-1); }int Delete(int &k,int Last){    if(!k) return 0;    int rtn;    if(num[k]+Delta<mn)    {        rtn=Delete(son[k][1],k)+sz[son[k][0]]+1;        sz[son[k][1]]=sz[k]-rtn;        k=son[k][1],fa[k]=Last;    }    else    {        rtn=Delete(son[k][0],k);        sz[k]-=rtn;    }    return rtn;}void Solve(){    while(n--)    {        char ch[1];int x;        scanf("%s",ch);x=read();        if(ch[0]=='I')         {            if(x>=mn)                Insert(rt,x-Delta,0);        }        else if(ch[0]=='A') Delta+=x;        else if(ch[0]=='S')         {            Delta-=x;            ans+=Delete(rt,0);        }        else        {            if(x>sz[rt]) printf("-1\n");            else            {                int k=Find(rt,x);                printf("%d\n",num[k]+Delta);                Splay(k,rt);            }        }    }    printf("%d\n",ans);}int main(){    n=read(),mn=read();    Solve();    return 0;}
0 0
原创粉丝点击