【bzoj1503】 NOI2004—郁闷的出纳员

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

题意

  要求维护4种操作:插入一个数,将所有数加上k,将所有数减去k,删去数值小于k的数并计算个数。

Solution

  splay。今天考试的时候询问时忘记下传标记了fuck dog

代码

// bzoj1503
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
 
const int maxn=500010;
int tr[maxn][2],size[maxn],val[maxn],sum[maxn],fa[maxn],tag[maxn];
int rt,cnt,S,n,ming,tot;
 
void update(int k) {
    int l=tr[k][0],r=tr[k][1];
    size[k]=size[l]+size[r]+sum[k];
}
void rotate(int x,int &k) {
    int y=fa[x],z=fa[y],l,r;
    l=tr[y][1]==x;r=l^1;
    if (k==y) k=x;
    else tr[z][tr[z][1]==y]=x;
    fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
    tr[y][l]=tr[x][r];tr[x][r]=y;
    update(y);update(x);
}
void splay(int x,int &k) {
    while (x!=k) {
        int y=fa[x],z=fa[y];
        if (y!=k) {
            if ((tr[z][0]==y) ^ (tr[y][0]==x)) rotate(x,k);
            else rotate(y,k);
        }
        rotate(x,k);
    }
}
void pushdown(int k) {
    val[tr[k][1]]+=tag[k];tag[tr[k][1]]+=tag[k];
    val[tr[k][0]]+=tag[k];tag[tr[k][0]]+=tag[k];
    tag[k]=0;
}
void insert(int x) {
    int k=rt,f=0;
    while (k) {
        if (tag[k]) pushdown(k);f=k;
        if (x<val[k]) k=tr[k][0];
        else if (x>val[k]) k=tr[k][1];
        else {sum[k]++;size[k]++;S++;splay(k,rt);return;}
    }
    S++;
    fa[++cnt]=f;sum[cnt]=size[cnt]=1;val[cnt]=x;tr[f][x>val[f]]=cnt;
    splay(cnt,rt);
}
int find(int x,int k) {
    if (tag[k]) pushdown(k);
    int ans=0;
    while (k) {
        if (tag[k]) pushdown(k);
        if (x==val[k]) return k;
        if (x<val[k]) ans=k,k=tr[k][0];
        else k=tr[k][1];
    }
    return ans;
}
void modify(int k) {
    val[rt]+=k,tag[rt]+=k;
    if (k<0) {
        int x=find(ming,rt);
        splay(x,rt);
        tot+=size[tr[x][0]];S-=size[tr[x][0]];tr[x][0]=0;
    }
}
int query(int x,int k) {
    if (tag[k]) pushdown(k);
    int l=tr[k][0],r=tr[k][1];
    if (x>=size[r]+1 && x<=size[r]+sum[k]) return k;
    else if (x<=size[r]) return query(x,r);
    else return query(x-size[r]-sum[k],l);
}
int main() {
    char ch[10];int k;
    tot=0;
    rt=cnt=1;val[1]=(1<<30);
    scanf("%d%d",&n,&ming);
    for (int i=1;i<=n;i++) {
        scanf("%s%d",ch,&k);
        if (ch[0]=='I') {if (k>=ming) insert(k);/*else tot++;*/}
        if (ch[0]=='A') modify(k);
        if (ch[0]=='S') modify(-k);
        if (ch[0]=='F') printf("%d\n",k>S ? -1 : val[query(k,rt)]);
    }
    printf("%d\n",tot);
    return 0;
}

  

posted @ 2016-10-10 15:34  MashiroSky  阅读(238)  评论(0编辑  收藏  举报