[伸展树]codevs1286 郁闷的出纳员

来源:互联网 发布:死亡岛有网络怎么联机 编辑:程序博客网 时间:2024/05/20 03:42

codevs1286 郁闷的出纳员

主要是删人的问题
找工资下界,找得到的话就把他的左子树删掉删掉!
如果没有人刚好在工资下界
那么….
找工资下界的后继,把后继的左子树删掉删掉!
如果后继为零,也就是说没有人的工资比下界还要大,把整棵树删掉
坑点:
建立工作档案的时候工资就低于工资下界的人不算辞职的人

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;int len,root;struct node{    int n,c,f,d,son[2]; } tr[100010];void update(int x){    int lc=tr[x].son[0],rc=tr[x].son[1];    tr[x].c=tr[x].n+tr[lc].c+tr[rc].c;}void add(int d,int f){    len++;    tr[len].d=d;tr[len].f=f;tr[len].c=1;tr[len].n=1;    tr[len].son[1]=tr[len].son[0]=0;    if (d<tr[f].d) tr[f].son[0]=len; else tr[f].son[1]=len; }int findip(int d){    int x=root;    while (tr[x].d!=d)    {        if (d<tr[x].d)        {            if (tr[x].son[0]==0) break;            else x=tr[x].son[0];         }        else        {            if (tr[x].son[1]==0) break;            else x=tr[x].son[1];        }    }    return x;}void rotate(int x,int w){    int f=tr[x].f,ff=tr[f].f;    int r,R;    r=tr[x].son[w];R=f;    tr[R].son[1-w]=r;    if (r!=0) tr[r].f=R;    r=x;R=ff;    tr[r].f=R;    if (f==tr[ff].son[0]) tr[R].son[0]=r;    else tr[R].son[1]=r;    r=f;R=x;    tr[r].f=R;    tr[R].son[w]=r;    update(f);    update(x);}void splay(int x,int rt){    while (tr[x].f!=rt)    {        int f=tr[x].f,ff=tr[f].f;        if (rt==ff)        {            if (tr[f].son[0]==x) rotate(x,1);            else rotate(x,0);        }        else         {            if (tr[f].son[0]==x&&tr[ff].son[0]==f) {rotate(f,1);rotate(x,1);}            else if (tr[f].son[1]==x&&tr[ff].son[1]==f) {rotate(f,0);rotate(x,0);}            else if (tr[f].son[0]==x&&tr[ff].son[1]==f) {rotate(x,1);rotate(x,0);}            else if (tr[f].son[1]==x&&tr[ff].son[0]==f) {rotate(x,0);rotate(x,1);}        }    }    if (rt==0) root=x;}void ins(int d){    if (root==0)    {        add(d,len);        root=len;        return ;    }    else     {        int x=findip(d);        if (d==tr[x].d)        {            tr[x].n++;            update(x);            splay(x,0);        }        else         {            add(d,x);            update(x);            splay(len,0);        }    }}void del(int d){    int x=findip(d);    splay(x,0);    if (tr[x].d!=d) return ;    if (tr[x].n>1) {tr[x].n--;update(x);return ;}    if (tr[x].son[0]==0&&tr[x].son[1]==0) {root=0;len=0;}    else if (tr[x].son[0]==0&&tr[x].son[1]!=0) {root=tr[x].son[1];tr[root].f=0;}    else if (tr[x].son[0]!=0&&tr[x].son[1]==0) {root=tr[x].son[0];tr[root].f=0;}    else    {        int p=tr[x].son[0];        while (tr[p].son[1]!=0) p=tr[p].son[1];        splay(p,x);        int R=p,r=tr[x].son[1];        tr[R].son[1]=r;        tr[r].f=R;        tr[R].f=0;        root=R;        update(R);    }}int findqianqu(int d){    int x=findip(d);splay(x,0);    if (tr[x].d>=d&&tr[x].son[0]!=0)    {        x=tr[x].son[0];        while (tr[x].son[1]!=0) x=tr[x].son[1];    }    if (tr[x].d>=d) x=0;    return x;}int findhouji(int d){    int x=findip(d);splay(x,0);    if (tr[x].d<=d&&tr[x].son[1]!=0)    {        x=tr[x].son[1];        while (tr[x].son[0]!=0) x=tr[x].son[0];    }    if (tr[x].d<=d) x=0;    return x;}int findpaiming(int d){    int x=findip(d);splay(x,0);    return tr[tr[x].son[0]].c+1;}int findnum(int k){    int x=root;    while (1)    {        int lc=tr[x].son[0],rc=tr[x].son[1];        if (k<=tr[lc].c) x=lc;        else if (k>tr[lc].c+tr[x].n)         {            k-=tr[lc].c+tr[x].n;            x=rc;        }        else break;    }    splay(x,0);    return tr[x].d;}void jiagongzi(int x,int d){    tr[x].d+=d;    if (tr[x].son[0]!=0) jiagongzi(tr[x].son[0],d);    if (tr[x].son[1]!=0) jiagongzi(tr[x].son[1],d);}int main(){    int n,meney=0,minm,die=0;    root=0;len=0;    scanf("%d%d",&n,&minm);    for (int i=1;i<=n;i++)    {        int a,b;char ch;        scanf("\n%c ",&ch);        if (ch=='I') {scanf("%d",&b);if (b<minm) {continue;}else ins(b);}        else if (ch=='A')         {             scanf("%d",&b);            jiagongzi(root,b);        }        else if (ch=='S')         {            scanf("%d",&b);            jiagongzi(root,-b);            int x=findip(minm);            if (tr[x].d>=minm)            {                splay(x,0);                if (tr[x].son[0]!=0)                {                       die+=tr[tr[x].son[0]].c;                    tr[x].son[0]=0;                    update(x);                }            }             else             {                x=findhouji(tr[x].d);                if (x==0)//如果后继为零,也就是说没有人的工资比下界还要大,把整棵树删掉                {                    die+=tr[root].c;                    root=0;len=0;                    continue;                }                splay(x,0);                if (tr[x].son[0]!=0)                {                    die+=tr[tr[x].son[0]].c;                    tr[x].son[0]=0;                    update(x);                }            }        }        else if (ch=='F') {scanf("%d",&b);if (b<=tr[root].c) printf("%d\n",findnum(tr[root].c+1-b));else printf("-1\n");}     }    printf("%d\n",die);    return 0;}
原创粉丝点击