zoukankan      html  css  js  c++  java
  • [BZOJ1862/Luogu2584][ZJOI2006]GameZ游戏排名系统

    题目链接:

    BZOJ1862

    Luogu2584

    就是一个裸的平衡树题。

    写了一颗(Splay)

    对于分数的覆盖,可以开(std::map)建立映射关系。

    可能这个原因常数太大了,(Luogu A)了,(BZOJ)(O2)也过不去。。

    一定是BZOJ太慢了

    #include <map>
    #include <cstdio>
    #include <cctype>
    #include <string>
    #include <iostream>
    
    inline char Getop()
    {
        register char c=getchar();
        while(c!='+'&&c!='?')c=getchar();
        return c;
    }
    
    inline long long Getll()
    {
        register long long x=0;
        register char c;
        while(!isdigit(c=getchar()));
        for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
        return x;
    }
    
    inline void Putint(int x)
    {
        register char Sta[15];
        register int Top=13;
        register char f=true;
        if(x<0)f=false,x=-x;
        for(Sta[13]='
    ',Sta[14]=0;Top==13||x;x/=10)Sta[--Top]=x%10^48;
        if(!f)Sta[--Top]='-';
        fwrite(Sta+Top,1,14-Top,stdout);
    }
    
    struct Splay_Tree
    {
        int Root,Nodn,TSiz;
        int Fa[250005];
        int Siz[250005];
        int Son[250005][2];
        long long Val[250005];
        std::map<long long,std::string> Nams;
        std::map<std::string,long long> Scos;
    
        inline void Update(int x)
        {
            if(!x)return;
            Siz[x]=1+Siz[Son[x][0]]+Siz[Son[x][1]];
        }
    
        inline int Relation(int x)
        {
            return Son[Fa[x]][1]==x;
        }
    
        inline void Rotate(int x)
        {
            int x_Fa=Fa[x],x_Fa2=Fa[x_Fa],Relat=Relation(x);
            Son[x_Fa][Relat]=Son[x][Relat^1];
            Fa[Son[x][Relat^1]]=x_Fa;
            Son[x][Relat^1]=x_Fa;
            Fa[x_Fa]=x;
            Fa[x]=x_Fa2;
            if(x_Fa2)Son[x_Fa2][Son[x_Fa2][1]==x_Fa]=x;
            Update(x_Fa),Update(x);
        }
    
        inline void Splay(int x)
        {
            for(register int x_Fa;x_Fa=Fa[x];Rotate(x))
                if(Fa[x_Fa])
                    if(Relation(x)==Relation(x_Fa))Rotate(x_Fa);
                    else Rotate(x);
            Root=x;
        }
    
        inline void Clear_Node(int x)
        {
            Son[x][0]=Son[x][1]=Fa[x]=Siz[x]=Val[x]=0;
        }
    
        inline void ToRoot(long long x)
        {
            for(register int Pos=Root;true;)
                if(x==Val[Pos])return Splay(Pos);
                else Pos=Son[Pos][x>Val[Pos]];
        }
    
        inline void Delete(std::string x)
        {
            --TSiz;
            ToRoot(Scos[x]);
            Nams.erase(Scos[x]);
            Scos.erase(x);
            if(!Son[Root][0]&&!Son[Root][1])return Clear_Node(Root);
            if(!Son[Root][0])
            {
                int Tmp=Root;
                Fa[Root=Son[Root][1]]=0;
                return Clear_Node(Tmp);
            }
            if(!Son[Root][1])
            {
                int Tmp=Root;
                Fa[Root=Son[Root][0]]=0;
                return Clear_Node(Tmp);
            }
            int Pre=Son[Root][0],Tmp=Root;
            while(Son[Pre][1])Pre=Son[Pre][1];
            Splay(Pre);
            Son[Root][1]=Son[Tmp][1];
            Fa[Son[Tmp][1]]=Root;
            Clear_Node(Tmp);
            Update(Root);
        }
    
        inline void Insert(long long x,std::string s)
        {
            ++TSiz;
            if(Scos.find(s)!=Scos.end())Delete(s);
            Nams[x]=s;
            Scos[s]=x;
            if(TSiz==1)
            {
                Root=++Nodn;
                Son[Root][0]=Son[Root][1]=Fa[Root]=0;
                Siz[Root]=1;
                Val[Root]=x;
                return;
            }
            for(register int Pos=Root,P_Fa=0;true;)
            {
                P_Fa=Pos;
                Pos=Son[Pos][x>Val[Pos]];
                if(!Pos)
                {
                    ++Nodn;
                    Son[Nodn][0]=Son[Nodn][1]=0;
                    Fa[Nodn]=P_Fa;
                    Siz[Nodn]=1;
                    Son[P_Fa][x>Val[P_Fa]]=Nodn;
                    Val[Nodn]=x;
                    Update(P_Fa);
                    return Splay(Nodn);
                }
            }
        }
    
        inline long long Get_Score_By_Rank(int x)
        {
            for(register int Pos=Root;true;)
                if(Siz[Son[Pos][0]]+1==x){Splay(Pos);return Val[Pos];}
                else if(Siz[Son[Pos][0]]>=x)Pos=Son[Pos][0];
                else x-=Siz[Son[Pos][0]]+1,Pos=Son[Pos][1];
        }
    
        inline int Query(std::string s)
        {
            ToRoot(Scos[s]);
            return Siz[Son[Root][1]]+1;
        }
    
        inline void Foreach(long long x)
        {
            register std::map<long long,std::string>::iterator it=Nams.find(Get_Score_By_Rank(TSiz-x+1));
            for(register int i=1;i<=10&&it!=Nams.end();++i,--it)
            {
                if(i!=1)putchar(' ');
                printf("%s",(*it).second.c_str());
                if(it==Nams.begin())break;
            }
            puts("");
        }
    
        inline void Debug()
        {
            for(register int i=1;i<=Nodn;++i)
                printf("%d %d %d %d %lld
    ",Fa[i],Siz[i],Son[i][0],Son[i][1],Val[i]);
        }
    }Tree;
    
    int n;
    
    int main()
    {
        scanf("%d",&n);
        for(register int i=1;i<=n;++i)
        {
            char op=Getop();
            std::string Name;
            if(op=='+')
            {
                std::cin>>Name;
                long long Score=Getll()*1000000LL+n-i;
                Tree.Insert(Score,Name);
            }
            else
            {
                char s[15];
                scanf("%s",s+1);
                if(isdigit(s[1]))
                {
                    long long Rank=0;
                    for(register int i=1;s[i];++i)Rank=(Rank<<3)+(Rank<<1)+(s[i]^48);
                    Tree.Foreach(Rank);
                }
                else
                {
                    for(register int i=1;s[i];++i)Name.push_back(s[i]);
                    Putint(Tree.Query(Name));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    sublime使用
    eclipse导入工程中文乱码
    npm 代理
    栈和堆
    Linux常用命令大全
    Google云开启SSH登录方法
    景安快运挂在磁盘-支持宝塔
    discuz 批量删除回复并且保留主题的方法,亲测3.4版本通过
    博客园去掉页面的广告的方法
    WordPress忘记后台登录地址时怎么办?万能登录地址
  • 原文地址:https://www.cnblogs.com/LanrTabe/p/10164410.html
Copyright © 2011-2022 走看看