zoukankan      html  css  js  c++  java
  • NOI2004 郁闷的出纳员

    大致题意就是对初始为空的数列的各种操作233


    题解:Splay啦~

    其中可能会遇到的几个问题:

    #1.如何删去低于min的点:
       找到数列中min的后继提为根,把根的左孩子丢(shan)了就完成了(很容易YY到的对吧~)
    #2.如何处理对当前数列中的数进行±k:
       开个全局变量存整体的波动(?)值ff。那么删点的时候就把低于min-ff的删掉;又是仅对于当前的数,于是后来插入的数要-ff再插入,以此来保证新插入的数不受先前操作的影响。
       p.s.输出的时候记得加上ff哦

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define maxn 101000
    
    struct node
    {
    	int d,c,n,f,son[2];
    }tr[maxn*2];int len,root;
    int ls,num,zs;//ls-上面说的ff;num-员工人数(算上离开了的?);zs-离开的员工数(就是最后要输出的那个)
    void updata(int x)
    {
    	int lc=tr[x].son[0],rc=tr[x].son[1];
    	tr[x].c=tr[lc].c+tr[rc].c+tr[x].n;
    }
    void add(int d,int f)
    {
    	len++;
    	tr[len].d=d;tr[len].f=f;
    	tr[len].c=tr[len].n=1;
    	tr[len].son[0]=tr[len].son[1]=0;
    	if (d<tr[f].d) tr[f].son[0]=len;else tr[f].son[1]=len;
    }
    void rotate(int x)
    {	
    	int y=tr[x].f,z=tr[y].f,w,r,R;
    	if (tr[y].son[0]==x) w=1;else w=0;
    	r=tr[x].son[w];R=y;
    	tr[R].son[1-w]=r;
    	if (r!=0) tr[r].f=R;
    	r=x;R=z;
    	tr[R].son[(tr[R].son[0]==y)?0:1]=r;
    	tr[r].f=R;
    	r=y;R=x;
    	tr[R].son[w]=r;
    	tr[r].f=R;
    	updata(y);updata(x);
    }
    void splay(int x,int rt)
    {
    	while (tr[x].f!=rt)
    	{
    		int y=tr[x].f,z=tr[y].f;
    		if (z==rt) rotate(x);
    		else
    		{
    			if ((y==tr[z].son[0])==(x==tr[y].son[0])) rotate(y);
    			else rotate(x);rotate(x);
    		}
    	}if (rt==0) root=x;
    }
    int findip(int d)
    {
    	int x=root;
    	while (tr[x].d!=d)
    	{
    		if (tr[x].d>d)
    		{
    			if (tr[x].son[0]!=0) x=tr[x].son[0];else break;
    		}else if (tr[x].d<d)
    		{
    			if (tr[x].son[1]!=0) x=tr[x].son[1];else break;
    		}
    	}return x;
    }
    void ins(int d)
    {
    	if (root==0) {add(d,0);root=len;return;}//每次都忘!!!!!!!
    	int x=findip(d);
    	if (tr[x].d==d) tr[x].n++;
    	else add(d,x);
    	updata(x);
    	splay(x,0);
    }
    void del(int d)
    {
    	int x=findip(d);splay(x,0);
    	while (tr[x].d<d)
    	{
    		if (tr[x].son[1]!=0)
    		{
    			x=tr[x].son[1];
    			while (tr[x].son[0]!=0) x=tr[x].son[0];
    		}else {zs+=tr[x].c;root=len=0;return;}
    	}splay(x,0);
    	if (tr[x].son[0]!=0) zs+=tr[tr[x].son[0]].c;
    	tr[x].son[0]=0;
    	updata(x);
    }
    int findpm(int k)
    {
    	int x=root;
    	while (1)
    	{
    		int lc=tr[x].son[0],rc=tr[x].son[1];
    		if (tr[rc].c>=k) x=rc;
    		else if (tr[rc].c+tr[x].n<k) {k-=tr[rc].c+tr[x].n;x=lc;}
    		else break;
    	}return tr[x].d;
    }
    int main()
    {
    	//freopen("cashier.in","r",stdin);
    	//freopen("cashier.out","w",stdout);
    	int n,minn,i,x;char c;
    	scanf("%d%d",&n,&minn);
    	ls=zs=num=len=root=0;
    	for (i=1;i<=n;i++)
    	{
    		scanf("
    %c%d",&c,&x);
    		if (c=='I')
    		{
    			if (x>=minn) {ins(x-ls);num++;}
    		}else if (c=='A') ls+=x;
    		else if (c=='S')
    		{
    			ls-=x;
    			del(minn-ls);
    		}else if (c=='F') 
    		{
    			if (x>num-zs) printf("-1
    ");
    			else printf("%d
    ",findpm(x)+ls);
    		}
    	}printf("%d
    ",zs);
    	return 0;
    }


  • 相关阅读:
    Express 框架中 使用ejs
    Nodejs操作MongoDB数据库
    MongoDB基础操作
    node中的包、npm和模块
    background
    animation
    transition
    transform
    【SpringCloud】各种组件的更新情况
    【SpringCloud】版本选择
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527879.html
Copyright © 2011-2022 走看看