[HAOI2008]排名系统 & [Zjoi2006]GameZ游戏排名系统 BZOJ1862&BZOJ1056

分析:

平衡树裸题,(学完LCT感觉自己不会普通的Splay了...),维护每个节点的权值大小顺序,和时间戳顺序,之后map维护一下是否存在过,(懒得写字符串hash了)。

附上代码:

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
using namespace std;
#define N 300055
#define ls ch[rt][0]
#define rs ch[rt][1]
#define get(rt) (ch[f[rt]][0]!=rt)
int ch[N][2],f[N],siz[N],val[N],rot,cnt,n;
map<string ,int >mp1;map<int ,string >mp2;
char s[205];
void PushUp(int rt){siz[rt]=siz[ls]+siz[rs]+1;}
void rotate(int rt)
{
    int x=f[rt],y=f[x],k=get(rt);
    ch[x][k]=ch[rt][!k];f[ch[x][k]]=x;
    ch[rt][!k]=x;f[x]=rt;f[rt]=y;
    if(x!=rot)ch[y][ch[y][0]!=x]=rt;
    PushUp(x);PushUp(rt);if(x==rot)rot=rt;
}
void Splay(int rt,int y)
{
    for(int fa;(fa=f[rt])!=y;rotate(rt))
        if(f[fa]!=y)
            rotate((get(rt)==get(fa))?fa:rt);
}
void insert(int v,int x)
{
    int l,r,rt=rot;
    while(rt){if(val[rt]>=v)r=rt,rt=ls;else l=rt,rt=rs;}
    Splay(l,0);Splay(r,rot);ch[r][0]=x;f[x]=r,val[x]=v,siz[x]=1;PushUp(r);PushUp(l);
}
void del(int rt)
{
    Splay(rt,0);
    int l=ch[rt][0],r=ch[rt][1];while(ch[l][1])l=ch[l][1];while(ch[r][0])r=ch[r][0];
    Splay(l,0);Splay(r,rot);ch[r][0]=0;f[rt]=0;siz[rt]=0;PushUp(r);PushUp(l);
}
int find(int x){int rt=rot;while(1){if(siz[ls]>=x)rt=ls;else{x-=siz[ls]+1;if(!x)return rt;rt=rs;}}}
int get_rank(int rt){Splay(rt,0);return siz[ls];}
void print(int rt)
{
    if(rs)print(rs);
    printf("%s ",mp2[rt].c_str());
    if(ls)print(ls);
}
void out_put(int x,int y)
{
    x=cnt-x-1;y=cnt-y-1;swap(x,y);
    //printf("%d %d\n",x,y);
    x=find(x),y=find(y+2);Splay(x,0);Splay(y,rot);print(ch[y][0]);
}
int main()
{
    char opt1=getchar();
    while(opt1>='0'&&opt1<='9')n=((n<<3)+(n<<1))+opt1-'0',opt1=getchar(); 
    val[1]=-1<<30;val[2]=2147483647;ch[1][1]=2;f[2]=1;rot=1;siz[1]=2;siz[2]=1;cnt=2;
    while(n--)
    {
        memset(s,0,sizeof(s));
        int num=0,x=0;
        opt1=getchar();while(opt1!='+'&&opt1!='?') opt1=getchar();
        if(opt1=='+')
        {
            opt1=getchar();
            while(opt1>='A'&&opt1<='Z')s[num++]=opt1,opt1=getchar();
            opt1=getchar();
            while(opt1<'0'||opt1>'9')opt1=getchar();
            while(opt1>='0'&&opt1<='9')x=((x<<3)+(x<<1))+opt1-'0',opt1=getchar();
            //printf("%d\n",mp1.count(s));
            if(mp1.count(s))
            {
                int y=mp1[s];
                del(y);
                insert(x,y);
            }else
            {
                cnt++;insert(x,cnt);mp1[s]=cnt;mp2[cnt]=s;
                //printf("%d\n",cnt);
            }
        }else
        {
            opt1=getchar();
            if(opt1>='0'&&opt1<='9')
            {
                while(opt1>='0'&&opt1<='9')x=((x<<3)+(x<<1))+opt1-'0',opt1=getchar();
                out_put(x,min(x+9,cnt-2));
                puts("");
            }else
            {
                while(opt1>='A'&&opt1<='Z')s[num++]=opt1,opt1=getchar();
                //Splay(5,0);printf("%d\n",siz[5]);
                printf("%d\n",cnt-get_rank(mp1[s])-1);
            }
        }
    }
    return 0;
}

  

posted @ 2018-06-06 11:14  Winniechen  阅读(130)  评论(0编辑  收藏  举报