bzoj 1503 平衡树

  我们可以用一颗平衡树维护每个人的工资,因为工资的变化会影响到后面所有的人,所以我们打一个标签,向平衡树里插入的时候减去这个标签的值,这样代表改变了之后的零点,,这样维护这个标签就好了,输出的时候要加上这个标签。

  反思:]后面打了个|,查了半天。。

/**************************************************************

    Problem: 1503

    User: BLADEVIL

    Language: C++

    Result: Accepted

    Time:676 ms

    Memory:3932 kb

****************************************************************/

 

//By BLADEVIL

#include <cstdio>

#define maxn 200010

 

using namespace std;

 

int t,tot,ans,mm;

int t_left[maxn],t_right[maxn],t_size[maxn],t_key[maxn];

 

void right_rotate(int &t){

    int k=t_left[t];

    t_left[t]=t_right[k];

    t_right[k]=t;

    t_size[k]=t_size[t];

    t_size[t]=t_size[t_right[t]]+t_size[t_left[t]]+1;

    t=k;

}   

 

void left_rotate(int &t){

    int k=t_right[t];

    t_right[t]=t_left[k];

    t_left[k]=t;

    t_size[k]=t_size[t];

    t_size[t]=t_size[t_left[t]]+t_size[t_right[t]]+1;

    t=k;

}

 

void maintain(int &t,bool flag){

    if (!flag) {

        if (t_size[t_left[t_left[t]]]>t_size[t_right[t]])

            right_rotate(t); else

        if (t_size[t_right[t_left[t]]]>t_size[t_right[t]])

            left_rotate(t_left[t]),right_rotate(t); else return;

    } else {

        if (t_size[t_right[t_right[t]]]>t_size[t_left[t]]) 

            left_rotate(t); else

        if (t_size[t_left[t_right[t]]]>t_size[t_left[t]])

            right_rotate(t_right[t]),left_rotate(t); else return;

    }

    maintain(t_left[t],0); maintain(t_right[t],1);

    maintain(t,1); maintain(t,0);

}

 

void t_insert(int &t,int v){

    if (!t) {

        t=++tot;

        t_left[t]=t_right[t]=0;

        t_size[t]=1;

        t_key[t]=v;

    } else {

        t_size[t]++;

        if (v<t_key[t]) t_insert(t_left[t],v); else t_insert(t_right[t],v);

        maintain(t,v>=t_key[t]);

    }

}

     

int t_rank(int &t,int k){

    if (k==t_size[t_right[t]]+1) return t_key[t];

    if (k<t_size[t_right[t]]+1) 

        return t_rank(t_right[t],k); else return t_rank(t_left[t],k-t_size[t_right[t]]-1);

}

 

int t_clear(int &t,int v){

    if (!t) return 0;

    int sum=0,tmp=0;

    if (t_key[t]<v) {

        sum=t_size[t_left[t]]+1;

        t_left[t]=0;

        t_size[t]-=sum;

        tmp=t_clear(t_right[t],v);

        sum+=tmp;

        t_size[t]-=tmp;

        t_size[t_right[t]]=t_size[t];

        t=t_right[t];

    } else {

        sum=t_clear(t_left[t],v);

        t_size[t]-=sum;

    }

    return sum;

}

 

int main(){

    //freopen("2.out","w",stdout);

    int n,m,k;

    scanf("%d%d",&n,&m);

    while (n--){

        char c[10];

        scanf("%s%d",&c,&k);

        if (c[0]=='I') {if (k>=m) t_insert(t,k-mm);} else

        if (c[0]=='F') if (k>t_size[t]) printf("-1\n"); else printf("%d\n",t_rank(t,k)+mm); else

        if (c[0]=='A') mm+=k; else mm-=k,ans+=t_clear(t,m-mm);

        //printf("|%d\n",sum);

        //printf("|%d %d\n",m,mm);

    }

    printf("%d\n",ans);

    return 0;

}

 

你可能感兴趣的:(ZOJ)