zoukankan      html  css  js  c++  java
  • BZOJ 1056: [HAOI2008]排名系统 && 1862: [Zjoi2006]GameZ游戏排名系统 Splay

    1056: [HAOI2008]排名系统

    Description

      排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名
    记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区
    段内的排名记录时,最多返回10条记录。

    Input

      第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Na
    me Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正
    整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名
    玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

    Output

      对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输
    出从第Index名开始的最多10名玩家姓名,用一个空格分隔。

    Sample Input

    20
    +ADAM 1000000 加入ADAM的得分记录
    +BOB 1000000 加入BOB的得分记录
    +TOM 2000000 加入TOM的得分记录
    +CATHY 10000000 加入CATHY的得分记录
    ?TOM 输出TOM目前排名
    ?1 目前有记录的玩家总数为4,因此应输出第1名到第4名。
    +DAM 100000 加入DAM的得分记录
    +BOB 1200000 更新BOB的得分记录
    +ADAM 900000 更新ADAM的得分记录(即使比原来的差)
    +FRANK 12340000 加入FRANK的得分记录
    +LEO 9000000 加入LEO的得分记录
    +KAINE 9000000 加入KAINE的得分记录
    +GRACE 8000000 加入GRACE的得分记录
    +WALT 9000000 加入WALT的得分记录
    +SANDY 8000000 加入SANDY的得分记录
    +MICK 9000000 加入MICK的得分记录
    +JACK 7320000 加入JACK的得分记录
    ?2 目前有记录的玩家总数为12,因此应输出第2名到第11名。
    ?5 输出第5名到第13名。
    ?KAINE 输出KAINE的排名

    Sample Output

    2
    CATHY TOM ADAM BOB
    CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
    WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
    4

    思路:

      splay板子题,不好调, 但是没什么思维难度 :名字用两个map互相对应就好了, 另外数据不符合题面, 最大的数可以达到$10^{10}$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <string>
    using namespace std;
    #define int long long 
    map<string, int>id;
    map<int, string>nam;
    #define ls ch[p][0]
    #define rs ch[p][1]
    const int N = 251000;
    const int inf = 100000000000000;
    int ch[N][2], siz[N], f[N], root, cnt;
    long long val[N];
    #define get(x) (ch[f[x]][1]==x)
    inline void up(int p) {
        if(p) siz[p] = siz[ls]+siz[rs]+1;
    }
    void rotate(int x) {
        int y=f[x], z=f[y], k=get(x);
        ch[y][k] = ch[x][k^1]; f[ch[y][k]] = y;
        ch[x][k^1] = y;
        f[y]=x, f[x] = z;
        if(z) ch[z][ch[z][1]==y]=x;
        up(y), up(x);
        if(y==root) root=x;
    }
    void splay(int x, int y) {
        for(int fa;(fa=f[x])!=y;rotate(x)) {
            if(f[fa]!=y) 
            rotate(get(x)==get(fa)?fa:x);
        }
    }
    void insert(int x, long long c) {
        int p = root;
        int l, r;
        while(p) {
            if(val[p]>=c) r=p, p=ls;
            else l=p, p=rs;
        }
        splay(l, 0);splay(r, root);
        ch[r][0] = x, f[x] = r;val[x] = c, siz[x] = 1;up(r), up(l);
    }
    void del(int x) {
        splay(x, 0);
        int l = ch[x][0], r=ch[x][1];
        while(ch[l][1]) l =ch[l][1];while(ch[r][0])r=ch[r][0];
        splay(l, 0); splay(r, root);
        ch[r][0]=0;
        f[x] = 0, siz[x] = 1;
        up(r), up(l);
    }
    void print(int p) {
        if(rs) print(rs);
        printf("%s ", nam[p].c_str());
        if(ls) print(ls);
    }
    int find(int x) {
        int p =root;
        while(1) {
            if(x<=siz[ls])p=ls;
            else {
                x-=siz[ls]+1;
                if(!x) return p;
                p=rs;
            }
        }
    }
    void qrk(int l, int r) {
        l=cnt-l-1, r=cnt-r-1;
        swap(l, r);
        l=find(l), r=find(r+2);
        splay(l, 0);
        splay(r, root);
        print(ch[r][0]);
        puts("");
    }
    #undef int
    int main() {
    #define int long long
        int n;
        val[1] = -inf, val[2] = inf;
        ch[1][1] = 2;f[2] =1;root=1;siz[1]=2, siz[2] = 1;cnt=2;
        scanf("%lld", &n);
        while(n--) {
            char c = getchar();
            while(c!='+'&&c!='?') c=getchar();
            char name[20];long long num;
            scanf("%s", name);
            if(c=='+') {
                scanf("%lld", &num);
                if(id.count(name)) {
                    int x = id[name];
                    del(x);
                    insert(x, num);
                }
                else {
                    cnt++;
                    insert(cnt, num);
                    id[name] = cnt;
                    nam[cnt] = name;
                }
            }
            else {
                if(isdigit(name[0])) {
                    int rk;
                    sscanf(name, "%lld", &rk);
                    qrk(rk, min(rk+9, cnt-2));
                }
                else {
                    int x = id[name];
                    splay(x, 0);
                    printf("%lld
    ", cnt-siz[ch[x][0]]-1);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    做嵌入式编程,为什么用的是C语言而不是C++呢?
    结对-四则运算答题器-设计文档
    Windows Forms Thread Safety: InvalidOperationException and Invoking
    DialogForm
    Views in Full Screen Mode
    Painting on a Panel
    A Gradient Title Bar for modal and modeless dialog
    MSN Messenger Type Status Bar Popup Message Box
    EZOptionsDlg
    Transparent Static Text In Dialogs
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9230741.html
Copyright © 2011-2022 走看看