• 洛谷 P1486 [NOI2004] 郁闷的出纳员(Splay)


    传送门


    解题思路

    平衡树板子题。
    每次所有的数加或减可以O(1)加或减限制,然后删除掉小于当前限制的点,统计答案。
    加点时把原权值减去sum然后扔到Splay中,询问第k大时也要把查询的答案加上一个sum。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<bitset>
    #include<stack>
    using namespace std;
    template<class T>inline void read(T &x)
    {
        x=0;register char c=getchar();register bool f=0;
        while(!isdigit(c))f^=c=='-',c=getchar();
        while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
        if(f)x=-x;
    }
    template<class T>inline void print(T x)
    {
        if(x<0)putchar('-'),x=-x;
        if(x>9)print(x/10);
        putchar('0'+x%10);
    }
    const int maxn=3e5+5;
    int n,rt,cnt,ans;
    long long sum,m;
    struct node{
    	int siz,cnt,son[2],fa;
    	long long val;
    }tr[maxn];
    void init(){
    	tr[rt].son[0]=tr[rt].son[1]=tr[rt].fa=tr[rt].siz=tr[rt].cnt=0;
    	rt=0;
    }
    int New(long long val,int fa){
    	cnt++;
    	tr[cnt].val=val;
    	tr[cnt].fa=fa;
    	tr[cnt].son[1]=tr[cnt].son[0]=0;
    	tr[cnt].cnt=tr[cnt].siz=1;
    	return cnt;
    }
    void update(int x){
    	tr[x].siz=tr[x].cnt;
    	if(tr[x].son[0]) tr[x].siz+=tr[tr[x].son[0]].siz;
    	if(tr[x].son[1]) tr[x].siz+=tr[tr[x].son[1]].siz;
    }
    void rotate(int x){
    	int y=tr[x].fa,z=tr[y].fa;
    	int c=(tr[y].son[1]==x);
    	tr[tr[x].son[!c]].fa=y;
    	tr[x].fa=tr[y].fa;
    	tr[y].fa=x;
    	if(z) tr[z].son[tr[z].son[1]==y]=x;
    	tr[y].son[c]=tr[x].son[!c];
    	tr[x].son[!c]=y;
    	update(y);
    	update(x);
    }
    void Splay(int x,int goal){
    	if(x==goal) return;
    	while(tr[x].fa!=goal){
    		int y=tr[x].fa,z=tr[y].fa;
    		if(z!=goal) ((tr[y].son[0]==x)^(tr[z].son[0]==y))?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!goal) rt=x;
    }
    void insert(long long val){
    	if(!rt){
    		rt=++cnt;
    		tr[rt].val=val;
    		tr[rt].cnt=tr[rt].siz=1;
    		return;
    	}
    	int x=rt;
    	while(1){
    		if(tr[x].val==val){
    			tr[x].cnt++;tr[x].siz++;
    			Splay(x,0);
    			return;
    		}
    		if(tr[x].son[tr[x].val<val]) x=tr[x].son[tr[x].val<val];
    		else{
    			tr[x].son[tr[x].val<val]=New(val,x);
    			Splay(cnt,0);
    			return;
    		}
    	}
    }
    long long get_val(int tot){
    	if(tot>tr[rt].siz) return -sum-1;
    	int x=rt;
    	while(1){
    		while((tr[x].son[1]?tr[tr[x].son[1]].siz:0)+tr[x].cnt<tot) tot-=(tr[x].son[1]?tr[tr[x].son[1]].siz:0)+tr[x].cnt,x=tr[x].son[0];
    		if(tr[x].son[1]==0||tot>tr[tr[x].son[1]].siz){
    			return tr[x].val;
    		}else{
    			x=tr[x].son[1];
    		}
    	}
    }
    void work(){
    	insert(m-sum);
    	if(tr[rt].son[0]) ans+=tr[tr[rt].son[0]].siz;
    	tr[rt].son[0]=0;
    	update(rt);
    	if(tr[rt].cnt>1) tr[rt].cnt--;
    	else{
    		if(tr[rt].son[1]) tr[tr[rt].son[1]].fa=0,rt=tr[rt].son[1];
    		else init();
    	}
    }
    int main(){
    	read(n);read(m);
    	for(int i=1;i<=n;i++){
    		char c=getchar();
    		while(c<'A'||c>'Z') c=getchar();
    		int x;read(x);
    		if(c=='I'){
    			if(x<m) continue;
    			insert(x-sum);
    		}else
    		if(c=='A'){
    			sum+=x;
    			work();
    		}else
    		if(c=='S'){
    			sum-=x;
    			work();	
    		}else{
    			print(get_val(x)+sum);
    			puts("");
    		}
    	}
    	print(ans);
    	return 0;
    }
    
  • 相关阅读:
    Nginx 413 Request Entity Too Large
    Docker 搭建一个多端同步网盘-Nextcloud
    FTP主动模式(PORT)与被动模式(PASV)
    Linux安装与使用FTP服务-vsftpd
    Mac FTP工具推荐-Transmit
    Nginx配置动静分离
    Nginx解决跨域问题(CORS)
    CentOS 7 之找回失落的ifconfig
    CentOS 7 之安装篇
    深入研究MiniMVC之后续篇
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15555328.html
Copyright © 2020-2023  润新知