前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【BZOJ 1503】郁闷的出纳员【权值线段树】

【BZOJ 1503】郁闷的出纳员【权值线段树】

作者头像
用户2965768
发布2019-07-08 17:59:59
4880
发布2019-07-08 17:59:59
举报
文章被收录于专栏:wym

 维护全局信息,结点记录该值出现的次数。

 支持全局k最小值,可增加删除,查找前驱,后继。相对平衡树,代码简单,快。

当数据较大时,需要离散化。

本题维护一个偏移量,当 A 操作时,不全都加工资 add+=x, S 操作 add-=x 。插入时x - add即可,这样仍然是全局偏移量。

输出+add - base就行,base 是防止负数出现

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
const int base = 200020;
const int maxn = 400020;
struct	T{
	int l,r,num,lazy;	
}t[maxn*4];// t[p] 表示值遇 l 到 r,num是该数出现次数   
char s[10];
int minn,add;
void build(int p,int l,int r){
	t[p].l = l;	 t[p].r = r; t[p].num = 0; t[p].lazy = 0;
	if(t[p].l==t[p].r) return ;
	int mid = (l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}
void lazy(int p){
	if(t[p].lazy==0)return ;
	else{
		t[p].lazy = 0; //t[p].num = 0;
		t[p*2].lazy = 1; t[p*2].num = 0;
		t[p*2+1].lazy = 1; t[p*2+1].num = 0;
	}
}
void insert(int p,int x){
	if(t[p].l==t[p].r){
		if(t[p].l==x){
			t[p].num++;//插入就是出现次数++,删除就是-- 
		}
		return ;
	}
	lazy(p);
	int mid = (t[p].l+t[p].r)>>1;
	if(x<=mid)insert(p*2,x);
	else insert(p*2+1,x);
	t[p].num = t[p*2].num + t[p*2+1].num;
}

void update(int p,int x){//工资低于x离开 
	if(t[p].r<x){
		t[p].num = 0; t[p].lazy = 1;
		return ;
	}
	if(t[p].l==t[p].r){
		if(t[p].r<x)t[p].num = 0;
		return ;
	}
	lazy(p);
	int mid = (t[p].l+t[p].r)>>1;
	if(x<=mid){
		update(p*2,x);
	}else{
		update(p*2,x);
		update(p*2+1,x);
	}
	t[p].num = t[p*2].num + t[p*2+1].num;
}
int ask(int p,int k){//查询全局第 k 小,第 n - k + 1 大
//查询n - k + 1小则为查询第k大 
	if(t[p].l==t[p].r)return t[p].l;
	lazy(p);
	if(k<=t[2*p].num)ask(p*2,k);
	else ask(p*2+1,k-t[p*2].num);
}
int main()
{
	int kk,x,sum = 0;
	scanf("%d%d",&kk,&minn);
	build(1,0,400100);
	for(int i=0;i<kk;i++)
	{
		scanf("%s%d",s,&x);
		if(s[0] == 'I')
		{
			if(x < minn) continue;
			sum++;
			insert(1,x-add+base);//add为偏移量,不总体操作 加base防负数
		}
		else if(s[0] == 'A')	add += x;
		else if(s[0] == 'S')
		{
			add -= x;
			update(1,minn-add+base);
		}
		else{
			if(x > t[1].num) printf("-1\n");
			else printf("%d\n",ask(1,t[1].num-x+1)+add-base);
		}
	}
	printf("%d\n",sum-t[1].num);
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年07月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档