首页 > 其他 > 详细

bzoj 1503 平衡树

时间:2014-02-26 16:54:07      阅读:246      评论:0      收藏:0      [点我收藏+]

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

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

bubuko.com,布布扣
/**************************************************************
    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;
}
bubuko.com,布布扣

bzoj 1503 平衡树

原文:http://www.cnblogs.com/BLADEVIL/p/3568080.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!