原题解地址:

 

https://www.luogu.org/blog/14559/solution-p1486

 

大致题意:

给出两个整数: 和 min

你需要写一种数据结构,并维护以下 n 个操作 (k 已给出  :

 命令 :输入 k 若 k>=min则插入 

 命令:将每个数加上 

 命令:将每个数减去  并删除所有小于min的数 。

 命令:查询第 k 大的数。

 

 

 

他——思路__妙,你们可以自己打开去看!下面是我整理的Code!

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
int n,mn,tot,rt,num,sum,s,k;
char op;

struct Node{
	int l,r,cnt,sz,val,da;
}a[100001];

inline void Update(int x){
	a[x].sz=a[x].cnt+a[a[x].l].sz+a[a[x].r].sz;
}

inline int New(int x){
	tot++;
	a[tot].val=x;
	a[tot].da=rand();
	a[tot].cnt=a[tot].sz=1;
	return tot;
}

inline void Build(){
	New(-INF);
	New(INF);
	rt=1;
	a[1].r=2;
	Update(rt);
}
//右旋 
inline void Zig(int &x){
	int y=a[x].l;
	a[x].l=a[y].r;
	a[y].r=x;
	x=y;
	Update(a[x].r);
	Update(x);
}
//左旋
inline int Zag(int &x){
	int y=a[x].r;
	a[x].r=a[y].l;
	a[y].l=x;
	x=y;
	Update(a[x].l);
	Update(x);
} 

void Insert(int &x,int val){
	if(!x){
		x=New(val);
		Update(x);
		return ;
	}
	if(val==a[x].val){
		a[x].cnt++;
		Update(x);
		return ;
	}
	if(val<a[x].val){
		Insert(a[x].l,val);
		if(a[x].da<a[a[x].l].da)
			Zig(x);
	}
	else{
		Insert(a[x].r,val);
		if(a[x].da<a[a[x].r].da)
			Zag(x);
	}
	Update(x);
}

void Delete(int &x,int val){
	if(!x) return ;
	if(a[x].val==val){
		if(a[x].cnt>1){
			a[x].cnt--;
			Update(x);
			return ;
		}
		if(a[x].l||a[x].r){
			if(!a[x].r||a[a[x].l].da>a[a[x].r].da){
				Zig(x);
				Delete(a[x].r,val);
			}
			else{
				Zag(x);
				Delete(a[x].l,val);
			}
			Update(x);
		}
		else x=0;
		return ;
	}
	if(val<a[x].val)
		Delete(a[x].l,val);
	else Delete(a[x].r,val);
	Update(x);
}

int Find_Rank(int x,int val){
	if(!x) return -1;
	if(a[a[x].l].sz>=val)
		return Find_Rank(a[x].l,val);
	if(a[a[x].l].sz+a[x].cnt>=val)
		return a[x].val;
	return Find_Rank(a[x].r,val-a[x].cnt-a[a[x].l].sz);
}

int Init(int val){
	int x=rt,ans=1;
	while(x){
		if(a[x].val==val){
			ans=x;
			break;
		}
		if(a[x].val<val&&a[x].val>a[ans].val) 
			ans=x;
		if(a[x].val<val) x=a[x].r;
		else x=a[x].l;
	}
	return a[ans].val;
}

int main(){
	scanf("%d%d",&n,&mn);
	Build();
	for(int i=1;i<=n;i++){
		scanf("\n");
		scanf("%c%d",&op,&k);
		if(op=='I')
			if(k-sum>=mn){
				Insert(rt,k-sum);
				num++;
				s++;
			}
		if(op=='F'){
			if(num<k)
				puts("-1");
			else
				printf("%d\n",Find_Rank(rt,num-k+2)+sum);
		}
		if(op=='A')
			mn-=k,sum+=k;
		if(op=='S'){
			mn+=k,sum-=k;
			int a1=mn-1,a2;
			while(Init(a1)!=-INF){
				a2=a1;
				a1=Init(a1);
				Delete(rt,Init(a2));
				num--;
			}
		}
	}
	printf("%d\n",s-num);
	return 0;
}

 

0 0 votes
文章评分
订阅这个评论
提醒

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
最旧
最新 得票最多
Inline Feedbacks
View all comments