zoukankan      html  css  js  c++  java
  • #Splay#洛谷 1486 [NOI2004]郁闷的出纳员

    题目


    分析

    考虑加减工资直接打标记,查询第(k)多可以用平衡树,
    删除有点恶心,这里考虑Splay,将需要删除的部分的后继splay到根节点并将左子树断边


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int inf=0x7fffffff,N=2000011;
    int n,mn,delta,ans;
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(int ans){
    	if (ans<0) putchar('-'),ans=-ans;
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    struct Splay{
    	int siz[N],cnt[N],son[N][2],fat[N],w[N],root,tot;
    	inline void pup(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];}
    	inline bool Is_R(int x){return son[fat[x]][1]==x;}
        inline void rotate(int x){
        	rr int Fa=fat[x],FFa=fat[Fa],wh=Is_R(x);
        	son[FFa][Is_R(Fa)]=x,fat[x]=FFa,son[Fa][wh]=son[x][wh^1],
        	fat[son[x][wh^1]]=Fa,son[x][wh^1]=Fa,fat[Fa]=x,pup(Fa),pup(x);
    	}
    	inline void splay(int x,int tar){
    		for (;fat[x]!=tar;rotate(x)){
    			rr int Fa=fat[x],FFa=fat[Fa];
    			if (FFa!=tar) rotate((Is_R(x)^Is_R(Fa))?x:Fa);
    		}
    		if (!tar) root=x;
    	}
        inline void Insert(int x){
        	rr int now=root,Fa=0;
        	while (now&&w[now]!=x)
        	    Fa=now,now=son[now][x>w[now]];
        	if (now) ++cnt[now];
        	else{
        		now=++tot;
        		if (Fa) son[Fa][x>w[Fa]]=now;
        		son[now][0]=son[now][1]=0,fat[now]=Fa,
    			w[now]=x,cnt[now]=siz[now]=1;
    		}
    		splay(now,0);
    	}
    	inline void Fsplay(int x){
    		rr int now=root;
    		if (!now) return;
    		while (son[now][x>w[now]]&&x!=w[now])
    		    now=son[now][x>w[now]];
    		splay(now,0);
    	}
    	inline signed pre(int x){
    		Fsplay(x);
    		rr int now=root;
    		if (w[now]<x) return now;
    		now=son[now][0];
    		while (son[now][1]) now=son[now][1];
    		return now;
    	}
    	inline signed suf(int x){
    		Fsplay(x);
    		rr int now=root;
    		if (w[now]>x) return now;
    		now=son[now][1];
    		while (son[now][0]) now=son[now][0];
    		return now;
    	}
        inline signed Delete(int x){
        	rr int L=1,R=suf(x);
        	splay(L,0),splay(R,L);
        	rr int ans=siz[son[R][0]];
    		son[R][0]=0,pup(R),pup(L);
    		return ans;
    	}
    	inline signed kth(int rk){
    		rr int now=root;
    		if (siz[now]<rk) return -1;
    		while (1){
    			rr int lson=son[now][0];
    			if (siz[lson]+cnt[now]<rk)
    				rk-=siz[lson]+cnt[now],now=son[now][1];
    				else if (rk<=siz[lson]) now=son[now][0];
    				    else break;
    		}
    		splay(now,0);
    		return w[now];
    	}
    	inline void BUILD(){Insert(-inf),Insert(inf);}
    }Tre;
    signed main(){
    	n=iut(),mn=iut(),Tre.BUILD();
    	for (rr int i=1;i<=n;++i){
    		rr char c=getchar();
    		while (!isalpha(c)) c=getchar();
    		switch (c){
    			case 'I':{
    				rr int x=iut();
    				if (x>=mn) Tre.Insert(x-delta); 
    				break;
    			}
    			case 'A':{
    				delta+=iut();
    				break;
    			}
    			case 'S':{
    				delta-=iut();
    				ans+=Tre.Delete(mn-delta-1);
    				break;
    			}
    			case 'F':{
    				rr int x=iut(),SIZ=Tre.siz[Tre.root];
    				if (SIZ-2>=x) print(Tre.kth(SIZ-x)+delta);
    				    else print(-1);
    				putchar(10); 
    				break;
    			}
    		}
    	}
    	return !printf("%d",ans);
    }
    
  • 相关阅读:
    Swift # Apple Pay集成
    GitHub Top 100 简介
    一些常用算法
    CocoaPods 建立私有仓库
    安装 CocoaPods & Alcatraz
    iOS程序 # 启动过程
    Apache & WebDav 配置(二)
    SVN & Git (二)
    SVN & Git (一)
    poj 3169 Layout (差分约束)
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13922414.html
Copyright © 2011-2022 走看看