zoukankan      html  css  js  c++  java
  • P4291 [HAOI2008]排名系统

    题目描述

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

    输入输出格式

    输入格式:

    第一行是一个整数n(10<=n<=250000)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下:

    +Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。

    ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。如果两个玩家的得分相同,则先得到该得分的玩家排在前面。

    ?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

    输出格式:

    对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。

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

    输入输出样例

    输入样例#1: 
    20
    +ADAM 1000000
    +BOB 1000000
    +TOM 2000000
    +CATHY 10000000
    ?TOM
    ?1
    +DAM 100000
    +BOB 1200000
    +ADAM 900000
    +FRANK 12340000
    +LEO 9000000
    +KAINE 9000000
    +GRACE 8000000
    +WALT 9000000
    +SANDY 8000000
    +MICK 9000000
    +JACK 7320000
    ?2
    ?5
    ?KAINE
    输出样例#1: 
    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

    Solution:

      本题纯模拟平衡树+hash

      这种动态加点、改值、查询排名和k大值的问题,直接想到平衡树。

      题目中需要用到的信息有:字符串、得分、时刻,其中时刻就是该字符串得到当前分数是第几次操作,维护时刻是因为对于得分相同的字符串,时刻小的要排在前面。

      我们用一棵Splay来维护pbds中的rb_tree来维护。

      对于每个字符串,把其和插入的时刻进行map映射,然后每个节点以分数为第一关键字、时刻为第二关键字,构建平衡树。对于每种操作:1、插入节点,直接可以insert ; 2、改变节点分数和时刻,我们直接改为删除这个节点,并加入新的值的节点 ; 3、查询排名,我们有order_of_key ; 4、查询第k大值,我们有find_by_order。

      只需要模拟就好了,减少了很多冗余的码农操作(pbds大法好!)

    代码:

    /*Code by 520 -- 9.21*/
    #include<bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/tree_policy.hpp>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    using namespace __gnu_pbds;
    const int N=500005;
    int n,val[N],cnt,tot;
    map<string,int> mp;
    string ss[N];
    struct node{
        int v,id;
        bool operator < (const node &x) const {return v==x.v?id<x.id:v>x.v;}
    };
    tree<node,null_type,less<node>,rb_tree_tag,tree_order_statistics_node_update> T;
    
    il bool isdig(char x){return x>='0'&&x<='9';}
    
    int main(){
        ios::sync_with_stdio(0);
        cin>>n;char c;string s;int x,tp;
        while(n--){
            cin>>c>>s;
            if(c=='+') {
                if(mp[s]) {
                    tp=mp[s],T.erase(node{val[tp],tp});tot--;
                }
                mp[s]=++cnt,cin>>val[cnt],T.insert(node{val[cnt],cnt});tot++;
                ss[cnt]=s;
            }
            else if(c=='?'&&!isdig(s[0])) {
                x=mp[s];cout<<T.order_of_key(node{val[x],x})+1<<endl;
            }
            else {
                x=0;
                For(i,0,s.size()-1) x=(x<<3)+(x<<1)+(s[i]^48);
                tp=min(tot,x+9);
                For(i,x-1,tp-1) cout<<ss[T.find_by_order(i)->id]<<' ';cout<<endl;
            }
        }
        return 0;
    }    
  • 相关阅读:
    JAVA语法之小结
    JAVA之经典Student问题1
    Android之动画1
    Android之屏幕测试
    Android之点击切换图片
    Android之标签选项卡
    Android简单计算器
    Javascript之相册拖动管理
    Javascript之改变盒子颜色
    CSS之照片翻转
  • 原文地址:https://www.cnblogs.com/five20/p/9690055.html
Copyright © 2011-2022 走看看