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; }