[BZOJ]1056 和 1862 splay

来源:互联网 发布:百度云管家mac版 编辑:程序博客网 时间:2024/05/09 22:35

可供复制的样例:

20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE

题解:

唉,我splay学得实在太差了,一道题调了一个下午……总结一下错误原因:1、add的时候没有把新节点的两个儿子变为0,这样在del的时候有可能会出问题。2、很弱智的错误,读入数字写成if(ch>=’1’&&ch<=’9’)。del和ins还不是很熟悉,rotate更是不会,还是听老师的多背背代码吧……

代码:

#include<cstdio>#include<cstring>#include<string>#include<map>#include<iostream>#include<algorithm>using namespace std;#define LL long longconst int maxn=250010;map<string,int>h;struct Splay{int size,son[2],f,d;LL s;string name;}tr[maxn*2];int root,z=0;void debug(){    for(int i=1;i<=z;i++)    printf("%d %d %d %d %d %lld ",i,tr[i].son[0],tr[i].son[1],tr[i].f,tr[i].d,tr[i].s),cout<<tr[i].name<<endl;//  puts("\n");    system("pause");//system("cls");}bool cmp(Splay x,Splay y)//true:x<y{    if(x.s!=y.s)return x.s<y.s;    return x.d>y.d;}void push_up(int x){    int lc=tr[x].son[0],rc=tr[x].son[1];    tr[x].size=tr[lc].size+tr[rc].size+1;}void add(int z,LL s,int f,string str,int d){    tr[z].s=s;tr[z].size=1;tr[z].d=d;    tr[z].f=f;tr[z].name=str;tr[z].son[0]=tr[z].son[1]=0;    if(cmp(tr[z],tr[f]))tr[f].son[0]=z;    else tr[f].son[1]=z;}void rotate(int x){    int w,y=tr[x].f,z=tr[y].f;    if(tr[y].son[0]==x) w=1;else w=0;    if(tr[x].son[w]) tr[tr[x].son[w]].f=y;    tr[y].son[1-w]=tr[x].son[w];//儿与父    if(x) tr[x].f=z;    if(tr[z].son[0]==y) tr[z].son[0]=x;    else tr[z].son[1]=x;//我与爷(取代父亲位置)    if(y) tr[y].f=x;    tr[x].son[w]=y;//父与我     push_up(y);push_up(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((tr[z].son[0]==y)==(tr[y].son[0]==x))            rotate(y);            else rotate(x);            rotate(x);        }    }    if(!rt)root=x;}int findpos(LL s,int d){    int now=root;    while(1)    {//      printf("%d\n",now);        int lc=tr[now].son[0],rc=tr[now].son[1];        if(s>tr[now].s)        {            if(rc)now=rc;            else break;        }        else if(s<tr[now].s)        {            if(lc)now=lc;            else break;        }        else        {            if(d>tr[now].d)            {                if(lc)now=lc;                else break;            }            else if(d<tr[now].d)            {                if(rc)now=rc;                else break;            }        }    }    return now;}void ins(int z,LL s,string str,int d){    if(root==0){add(z,s,0,str,d);root=z;return;}    int x=findpos(s,d);    add(z,s,x,str,d);    push_up(x);splay(x,0);}void del(int x){    splay(x,0);    if(!tr[x].son[0]&&!tr[x].son[1]){root=z=0;return;}    if(!tr[x].son[0]&&tr[x].son[1]){root=tr[x].son[1];tr[tr[x].son[1]].f=0;return;}    if(tr[x].son[0]&&!tr[x].son[1]){root=tr[x].son[0];tr[tr[x].son[0]].f=0;return;}    int now=tr[x].son[0];    while(tr[now].son[1])now=tr[now].son[1];    splay(now,x);root=now;tr[root].f=0;    tr[root].son[1]=tr[x].son[1];    tr[tr[x].son[1]].f=root;    push_up(root);}//z s f strint findren(int rank){    int now=root;    while(rank)    {        int lc=tr[now].son[0],rc=tr[now].son[1];        if(rank<=tr[lc].size)now=lc;        else if(rank==tr[lc].size+1)break;        else rank-=(tr[lc].size+1),now=rc;    }    return now;}void split(int l,int r)//让l,r这段区间独立出来  {  //  printf("%d %d %d\n",l,r+2,z);    int x=findren(l),y=findren(r+2);    splay(x,0);splay(y,x);}bool tf;void print(int x){    if(tr[x].son[1])print(tr[x].son[1]);       if(tf)tf=false;    else printf(" ");    int L=tr[x].name.size();    for(int i=0;i<L;i++)printf("%c",tr[x].name[i]);    if(tr[x].son[0])print(tr[x].son[0]);}int main(){    add(++z,(1LL<<55),0,"",0);    add(++z,-(1LL<<55),1,"",0);    root=1;    int T,D=0;    LL score;    scanf("%d",&T);    while(T--)    {        char op=getchar(),ch;        string str;        while(op!='?'&&op!='+')op=getchar();        if(op=='+')        {            D++;            while(1)            {                ch=getchar();                if(ch==' ')break;                str+=ch;            }            scanf("%lld",&score);            if(h[str]==0)h[str]=++z,ins(z,score,str,D);            else             {                del(h[str]);                ins(h[str],score,str,D);            }        }        else        {            ch=getchar();            if(ch>='0'&&ch<='9')            {                int num=ch-'0';                while(1)                {                    ch=getchar();                    if(!(ch>='0'&&ch<='9'))break;                    num=num*10+ch-'0';                }                int l=num,r=min(l+9,z-2);                swap(l,r);//              printf("%d %d %d %d\n",l,r,z-1-l,z-1-r);                split(z-1-l,z-1-r);                tf=true;                print(tr[tr[root].son[1]].son[0]);                puts("");            }            else            {                str+=ch;                while(1)                {                    ch=getchar();                    if(ch=='\n')break;                    str+=ch;                }                int x=h[str];                splay(x,0);                printf("%d\n",z-1-tr[tr[x].son[0]].size);            }        }    }}
原创粉丝点击