平衡树本地AC,洛谷全WA
查看原帖
平衡树本地AC,洛谷全WA
399936
辰云楼主2022/1/23 22:23
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define NULL nullptr
using namespace std;

int mi,sum,leave;

struct Node{
	Node* ch[2];
	int r,v,s,flag;
	Node(int v){this->v=v;r=rand();s=1;flag=1;ch[0]=ch[1]=NULL;}
	int cmp(int x){
		if(x==v)return -1;
		return x<v ? 0 : 1;
	}
	void maintain(){
		s=flag;
		if(ch[0]!=NULL)s+=ch[0]->s;
		if(ch[1]!=NULL)s+=ch[1]->s;
	}
};

inline void turn(Node* &o,int d){
	Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
	o->maintain();k->maintain();o=k;
}

void insert(Node* &o,int x){
	if(o==NULL)o=new Node(x);
	else{
		int d=o->cmp(x);
		if(d==-1)o->flag++;
		else{
			insert(o->ch[d],x);
			if(o->ch[d]->r > o->r)turn(o,d^1);
		}
	}
	o->maintain();
}

void del(Node* &o){
	if(o==NULL)return ;
	if(o->v + sum >= mi){
		del(o->ch[0]);
		o->maintain();
	}
	else{
		while(o->v + sum < mi){
			if(o->ch[1]==NULL){
				leave+=o->s;
				o=NULL;
				return ;
			}
			turn(o,0);
		}
		leave+=o->ch[0]->s;
		o->ch[0]=NULL;
		o->maintain();
	}
}

int getrank(Node* o,int k){
	if(k<0||k>o->s||o==NULL)return 0;
	int ss=0;
	if(o->ch[0]!=NULL)ss=o->ch[0]->s;
	if(k>=ss+1&&k<=o->flag+ss)return o->v;
	if(ss>=k) return getrank(o->ch[0],k);
	else return getrank(o->ch[1],k - ss - o->flag);
}

Node* root;

int main(){
	root=NULL;
	int n;
	scanf("%d%d",&n,&mi);
	while(n--){
		char s[5];int k;
		scanf("%s%d",s,&k);
		if(s[0]=='I'){
			if(k>=mi)insert(root,k-sum);
		}else if(s[0]=='A'){
			sum+=k;
		}else if(s[0]=='S'){
			sum-=k;
			del(root); 
		}else {
			if(root==NULL)printf("%d\n",-1);
			else if(k>root->s)printf("%d\n",-1);
			else printf("%d\n",getrank(root,root->s-k+1)+sum);
		}
	}
	printf("%d",leave);
	return 0;
}
2022/1/23 22:23
加载中...