• [HAOI2008] 排名系统


    题目链接:戳我

    要注意因为数可能会对应很多人,但是输出的时候要按照添加的顺序输出。所以我们不能将相同值的节点合并,用set维护。就算值相同也只能新开节点。

    然后就没有什么了。。。懒得写哈希表。。直接上map了。。开了O2之后也不是很慢qwq

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #define ll long long
    #define MAXN 6400010
    #define ls (t[x].ch[0])
    #define rs (t[x].ch[1])
    using namespace std;
    int rt,n,tot;
    map<string,int> M;
    string kkk,name[250010];
    struct Node{int ch[2],ff,v,size;}t[MAXN];
    
    void push_up(int x){t[x].size=t[ls].size+t[rs].size+1;}
    
    inline void rotate(int x)
    {
        int y=t[x].ff;
        int z=t[y].ff;
        int k=t[y].ch[1]==x;
        t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
        t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y; t[y].ff=x;
        push_up(y),push_up(x);
    }
    
    void splay(int x,int goal)
    {
        while(t[x].ff!=goal)
        {
            int y=t[x].ff,z=t[y].ff;
            if(z!=goal)
                (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
            rotate(x);
        }
        if(!goal)rt=x;
    }
    
    void insert(int u,int id)
    {
        int x=rt;
        for(;;)
        {
            if(!t[x].ch[u>t[x].v])
            {
                t[id].ff=x;t[id].v=u;t[id].size=1;
                t[x].ch[u>t[x].v]=id;
                splay(id,0);
                break;
            }
            else x=t[x].ch[u>t[x].v];
        }
    }
    
    int _th(int K)
    {
        int x=rt;
        for(;;)
        {
            if(t[ls].size+1==K) return x;
            else if(t[ls].size>=K) x=ls;
            else K-=t[ls].size+1,x=rs;
        }
    }
    
    void Del(int x)
    {
        splay(x,0);
    	int rk=t[ls].size;
        int l=_th(rk),r=_th(rk+2);
        splay(l,0);splay(r,l);t[r].ch[0]=0;
        t[x].ff=t[x].size=t[x].v=0;
        push_up(r);
        push_up(l);
    }
    
    void print(int x,int &sum)
    {
        if(!sum)return;
        if(rs)print(rs,sum);
        if(!sum)return;
        if(x>2)
            sum--,cout<<name[x]<<" ";
        if(ls)print(ls,sum);
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        insert(-2147483647,++tot);insert(2147483647,++tot);
        while(n--)
        {
            char op;
            cin>>op;
            cin>>kkk;
            if(op=='+')
            {
                int sco,id;
                scanf("%d",&sco);
                if(M[kkk])id=M[kkk],Del(id),insert(sco,id);
                else
                {
                    insert(sco,M[kkk]=++tot);
                    name[tot]=kkk;
                }
            }
            else if(kkk[0]>='0'&&kkk[0]<='9')
            {
                int rk=0,l=kkk.length();
        		for(int i=0;i<l;++i) rk=rk*10+kkk[i]-'0';
                l=_th(tot-rk+1);
                splay(l,0);
    			int sum=10;
                print(t[l].ch[0],sum);puts("");
            }
            else
            {
                int x=M[kkk];splay(x,0);
                printf("%d
    ",t[rs].size);
            }
            if(n%200==0) splay(rand()%tot+1,0);
        }
        return 0;
    }
    

    这道题过一段时间之后还要重写。。。实在是奇葩qwq

  • 相关阅读:
    Java三大特性与实战
    Java数组
    Java流程控制,for,switch,while.break,continue,return
    洛谷——P1498 南蛮图腾
    洛谷——P1010 幂次方
    洛谷——P1147 连续自然数和
    洛谷——P1514 引水入城
    洛谷——1538 迎春舞会之数字舞蹈
    普及练习场之排序Ex
    普及练习场之排序
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10420827.html
Copyright © 2020-2023  润新知