[NOI2004]郁闷的出纳员

一道平衡树的题。
当时用pb_ds胡搞过了,但发现我的数据结构好鱼.。
2018.7.9修改:比数据结构更鱼的是dp
线段树可以搞,就是维护一个桶,然后支持单点添加,区间赋值,记一个detla,记录工资的加减。为防止工资出现负数,做桶时候RE,加一个100001,query后减去。
Orz:http://www.cnblogs.com/lkhll/p/7290169.html
(#define czq A+k)

#include <cstdio>
#define czq A+k
const int A=10005,N=300001;
int n,min,detla,ans;
char opt[10];
struct Seg {
	int sum,lazy;
} t[N<<2];
void pushup(int cur) {
	if(!t[cur].lazy)return;
	t[cur<<1].lazy=t[cur<<1|1].lazy=1;
	t[cur<<1].sum=t[cur<<1|1].sum=0;
	t[cur].lazy=0;
}
void modify(int cur,int l,int r,int L,int R,int x,bool f) {
	if(l==L&&r==R) {
		if(f)t[cur].sum++;
		else t[cur].sum=x,t[cur].lazy=1;
		return;
	}
	pushup(cur);
	int mid=l+r>>1;
	if(R<=mid) modify(cur<<1,l,mid,L,R,x,f);
	else if(mid<L) modify(cur<<1|1,mid+1,r,L,R,x,f);
	else modify(cur<<1,l,mid,L,mid,x,f),
	modify(cur<<1|1,mid+1,r,mid+1,R,x,f);
	t[cur].sum=t[cur<<1].sum+t[cur<<1|1].sum;
}
int query(int cur,int L,int R,int kth) {
	if(L==R) return L;
	pushup(cur);
	int mid=(L+R)>>1;
	if(t[cur<<1|1].sum>=kth) return query(cur<<1|1,mid+1,R,kth);
	return query(cur<<1,L,mid,kth-t[cur<<1|1].sum);
}
int main() {
	scanf("%d%d",&n,&min);
	min+=A;
	for(int i=1,k; i<=n; i++) {
		scanf("%s%d",opt,&k);
		if(opt[0]=='I') {
			if(czq>=min) ans++,modify(1,1,N,czq-detla,czq-detla,1,1);
		} else if(opt[0]=='A') detla+=k;
		else if(opt[0]=='S') {
			detla-=k;
			if(min-detla>1)	modify(1,1,N,1,min-detla-1,0,0);
		} else {
			if(t[1].sum>=k)
				printf("%d
",query(1,1,N,k)+detla-A);
			else puts("-1");
		}
	}
	printf("%d",ans-t[1].sum);
}
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9261761.html