• [ZJOI2006]GameZ游戏排名系统


    Description
    GameZ为他们最新推出的游戏开通了一个网站。世界各地的玩家都可以将自己的游戏得分上传到网站上。这样就可以看到自己在世界上的排名。得分越高,排名就越靠前。当两个玩家的名次相同时,先上传记录者优先。由于新游戏的火爆,网站服务器已经难堪重负。为此GameZ雇用了你来帮他们重新开发一套新的核心。排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时最多返回10条记录。

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

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

    Sample Input
    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

    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的基本操作便可以

    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=3e5;
    map<string,int>si;
    map<int,string>is;
    struct Splay{
    	#define T(x) (tree[f[x]][1]==x)
    	#define ls(x)	tree[x][0]
    	#define rs(x)	tree[x][1]
    	int tree[N+10][2],f[N+10],size[N+10],val[N+10];
    	int root,len,cnt,tot;
    	void write(int x){
    		if (!x)	return;
    		write(rs(x));
    		if (abs(x)!=inf){
    			printf("%s",is[x].c_str());
    			++cnt!=tot?putchar(' '):putchar('
    ');
    		}
    		write(ls(x));
    	}
    	void init(){
    		root=len=2;
    		val[1]=-inf,val[2]=inf;
    		f[tree[root][0]=1]=2;
    		size[1]=1,size[2]=2;
    	}
    	void updata(int x){size[x]=size[ls(x)]+size[rs(x)]+1;}
    	void move(int x){
    		int fa=f[x],son=tree[x][T(x)^1];
    		tree[x][T(x)^1]=fa;
    		tree[fa][T(x)]=son;
    		if (son)	f[son]=fa;
    		f[x]=f[fa];
    		if (f[x])	tree[f[x]][T(fa)]=x;
    		f[fa]=x;
    		updata(fa),updata(x);
    	}
    	void splay(int x){
    		while (f[x]){
    			if (f[f[x]])	T(x)==T(f[x])?move(f[x]):move(x);
    			move(x);
    		}
    		root=x;
    	}
    	int find(int x,int i){
    		if (size[ls(i)]+1==x)	return i;
    		if (x<=size[ls(i)])	return find(x,ls(i));
    		return find(x-size[ls(i)]-1,rs(i));
    	}
    	int get_pre(){
    		int x=ls(root);
    		while (rs(x))	x=rs(x);
    		return x;
    	}
    	int get_suc(){
    		int x=rs(root);
    		while (ls(x))	x=ls(x);
    		return x;
    	}
    	void Delete(int x){
    		splay(x);
    		if (!(ls(x)&&rs(x))){
    			f[root=ls(x)+rs(x)]=0;
    			f[x]=ls(x)=rs(x)=size[x]=0;
    			return;
    		}
    		int i=get_pre();
    		splay(i);
    		f[rs(i)=rs(x)]=i;
    		f[x]=ls(x)=rs(x)=size[x]=0;
    	}
    	void insert(string s,int v){
    		if (si[s])	Delete(si[s]);
    		is[si[s]=++len]=s;
    		val[len]=v;
    		if (!root){size[root=len]=1;return;}
    		int i=root;
    		while (1){
    			size[i]++;
    			if (v<=val[i]){
    				if (!tree[i][0]){f[tree[i][0]=len]=i;break;}
    				i=tree[i][0];
    			}else{
    				if (!tree[i][1]){f[tree[i][1]=len]=i;break;}
    				i=tree[i][1];
    			}
    		}
    		splay(len);
    	}
    	void query(int x){
    		int r=size[root]-x-1,l=max(1,r-9);
    		tot=r-l+1,cnt=0;
    		l=find(l,root),splay(l);
    		r=find(r+2,root),splay(r);
    		if (f[l]!=root)	move(l);
    		write(tree[l][1]);
    	}
    	void get_Rank(string s){
    		int x=si[s];
    		splay(x);
    		printf("%d
    ",size[rs(x)]);
    	}
    }T;
    int change(string s){
    	int x=0;
    	for (int i=0;i<(int)s.length();i++)	x=(x<<1)+(x<<3)+s[i]-'0';
    	return x;
    }
    int main(){
    	T.init();
    	si.clear(),is.clear();
    	int n=read();
    	char ch,c[15];
    	string s;
    	for (int i=1;i<=n;i++){
    		for (ch=getchar();ch!='+'&&ch!='?';ch=getchar());
    		scanf("%s",c);
    		s=string(c);
    		if (ch=='+')	T.insert(s,read());
    		if (ch=='?'){
    			if (s[0]>='0'&&s[0]<='9'){
    				int x=change(s);
    				T.query(x);
    			}else	T.get_Rank(s);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据库-自定义函数
    数据库-存储过程
    数据库配置
    水电费管理系统需求分析与设计_待完善
    SQL中Group By的使用
    部分查询功能语句
    10-11数据库练习
    Oracle-SQL
    开发环境之Gradle
    解决程序端口占用
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9479464.html
Copyright © 2020-2023  润新知