1056: [HAOI2008]排名系统&1862: [Zjoi2006]GameZ游戏排名系统&codevs 1985

来源:互联网 发布:几个程序员去吃饭 编辑:程序博客网 时间:2024/05/18 22:42

要求打一个数据结构,支持单点修改,单点排名查询,区间排名查询。

Splay模板题。

可以多加两个节点在两边,开个数组记录玩家在Splay上的位置。

然而bzoj卡cin,又懒,不想打哈希,于是愉快的精神AC了。

可以交codevs:http://codevs.cn/problem/1985/


手贱错误:

del操作while(tr[p].son[1]!=0) p=tr[p].son[1];   不要手贱成while(tr[p].son[1]!=0) p=tr[x].son[1];
ins操作后要更新x节点


code:

#include<cstdio>#include<cstring>#include<cstdlib>#include<map>#include<string>#include<iostream>#define LL long longusing namespace std;const LL inf=(1LL<<55);const int maxn=1320020;struct trnode{    int d2,id,c,son[2],fa;//d1是权值 d2是位置权     LL d1;}tr[maxn];int root=0,len=0,n;map <string ,int> name;struct node{    string s;    int id,len;}a[maxn];int num=0,tot=0;void update(int x){    int lc=tr[x].son[0],rc=tr[x].son[1];    tr[x].c=tr[lc].c+tr[rc].c+1;}bool big(LL x1,int x2,LL y1,int y2){    if(x1>y1) return true;    if(x1<y1) return false;    return x2<y2;}void add(LL d1,int d2,int fa,int id,int x){    tr[x].d1=d1;tr[x].d2=d2;tr[x].c=1;tr[x].id=id;    tr[x].son[0]=tr[x].son[1]=0;tr[x].fa=fa;    tr[fa].son[big(d1,d2,tr[fa].d1,tr[fa].d2)?0:1]=x;}void rotate(int x){    int y=tr[x].fa,z=tr[y].fa,w,R,r;    w=tr[y].son[0]==x?1:0;    R=y;r=tr[x].son[w];    tr[R].son[1-w]=r;    if(r!=0) tr[r].fa=R;    R=z;r=x;    tr[R].son[tr[z].son[0]==y?0:1]=r;    if(r!=0) tr[r].fa=R;    R=x;r=y;    tr[R].son[w]=r;    if(r!=0) tr[r].fa=R;    update(y);update(x);}void splay(int x,int fa){    while(tr[x].fa!=fa)    {        int y=tr[x].fa,z=tr[y].fa;        if(z==fa) rotate(x);        else            if((tr[z].son[0]==y)==(tr[y].son[0]==x)) rotate(y),rotate(x);            else rotate(x),rotate(x);    }    if(fa==0) root=x;}int findid(LL d1,int d2){    int x=root;    while(1)    {        int lc=tr[x].son[0],rc=tr[x].son[1];        if(big(d1,d2,tr[x].d1,tr[x].d2))            if(lc==0) break;            else x=lc;        else            if(rc==0) break;            else x=rc;    }    return x;}int findip(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+1) k-=(tr[lc].c+1),x=rc;        else break;    }    return x;}void ins(LL d1,int d2,int id,int tmp){    if(root==0){add(d1,d2,0,id,tmp);root=tmp;return;}    int x=findid(d1,d2);    add(d1,d2,x,id,tmp);    update(x);splay(x,0);}void del(int x){    splay(x,0);    if(tr[x].son[0]==0&&tr[x].son[1]==0){root=len=0;return;}    if(tr[x].son[0]!=0&&tr[x].son[1]==0){tr[tr[x].son[0]].fa=0;root=tr[x].son[0];return;}    if(tr[x].son[0]==0&&tr[x].son[1]!=0){tr[tr[x].son[1]].fa=0;root=tr[x].son[1];return;}    int p=tr[x].son[0];    while(tr[p].son[1]!=0) p=tr[p].son[1];    splay(p,x);root=p;tr[root].fa=0;    tr[root].son[1]=tr[x].son[1];    tr[tr[x].son[1]].fa=root;    update(root);}void solve(int l,int r)//让l,r这段区间独立出来{    int x=findip(l),y=findip(r+2);    splay(x,0);splay(y,x);}bool first;void print(int x){    if(tr[x].son[0]!=0) print(tr[x].son[0]);    int id=tr[x].id;    if(first) first=false;    else printf(" ");    for(int i=1;i<a[id].len;i++) printf("%c",a[id].s[i]);    if(tr[x].son[1]!=0) print(tr[x].son[1]);}int main(){    scanf("%d",&n);    add(inf,-99999999,0,0,++len);add(-inf,99999999,1,0,++len);    root=1;string ch;    while(n--)    {        cin>>ch;        if(ch[0]=='+')        {            LL d1;scanf("%lld",&d1);            if(name[ch]==0)            {                name[ch]=++num;a[num].s=ch;a[num].id=++len;                ins(d1,++tot,num,len);a[num].len=ch.size();            }            else            {                int id=name[ch],x=a[id].id;del(x);                ins(d1,++tot,id,x);            }        }        else            if('A'<=ch[1]&&ch[1]<='Z')            {                ch[0]='+';int id=name[ch];                int x=a[id].id;splay(x,0);                printf("%d\n",tr[tr[x].son[0]].c);            }            else            {                int tmp=ch.size();int l=0;                for(int i=1;i<tmp;i++) l=l*10+ch[i]-'0';                int r=min(num,l+9);solve(l,r);                first=true;                print(tr[tr[root].son[1]].son[0]);                cout<<endl;            }    }}


阅读全文
2 0