[haoi2008]排名系统

蛤省省选题。

一道彻头彻尾的码农题。

该题的主要知识点有:字符串hash,平衡树。(两颗平衡树?)。

4T用splay怎么都调不过。可能是由于splay常数太大。(想写treap,但又实在不想写)。

字符串hash不想写啊,用map水的话时限卡着。

这题就当我过了吧...

过不去的程序:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<ctime>
#include<queue>
using namespace std;
#define LL long long
#define FILE "dealing"
#define eps 1e-10
#define db double
#define pii pair<int,int>
#define up(i,j,n) for(int i=j;i<=n;i++)
int read(){
	int x=0,f=1,ch=getchar();
	while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘)x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar();
	return x*f;
}
const int maxn=600000,mod=1000000007,inf=1000000007;
bool cmin(int& a,int b){return a>b?a=b,true:false;}
bool cmax(int& a,int b){return a<b?a=b,true:false;}
int n;
//namespace tree{
	int siz[maxn],c[maxn][2],cnt=0,rt,fa[maxn];
	pii val[maxn];
	void updata(int x){siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;}
	void rotate(int x){
		int y=fa[x],z=fa[y],d=c[y][1]==x;
		if(z)c[z][c[z][1]==y]=x;
		fa[y]=x;fa[x]=z;if(c[x][d^1])fa[c[x][d^1]]=y;
		c[y][d]=c[x][d^1],c[x][d^1]=y;
		updata(y);updata(x);
	}
	void splay(int x,int S){
		while(fa[x]!=S){
			int y=fa[x],z=fa[y];
			if(z!=S){
				if(c[z][1]==y^c[y][1]==x)rotate(x);
				else rotate(y);
			}
			rotate(x);
		}
		if(!S)rt=x;
	}
	int getK(int k){//右边有k个数的数
		int x=rt;
		while(x){
			if(k==siz[c[x][1]])return x;
			if(k>siz[c[x][1]])k-=(siz[c[x][1]]+1),x=c[x][0];
			else x=c[x][1];
		}
		return -1;
	}
	int insert(pii key){
		if(!rt){rt=++cnt;val[rt]=key;siz[rt]=1;return rt;}
		int x=rt,y;
		while(x){
			y=x;
			x=c[x][key>val[x]];
		}
		x=++cnt;
		fa[x]=y;
		val[x]=key;
		siz[x]=1;
		c[y][key>val[y]]=x;
		updata(y);
		splay(y,0);
		return x;
	}
	int findl(int x){x=c[x][0];while(c[x][1])x=c[x][1];return x;}
	int findr(int x){x=c[x][1];while(c[x][0])x=c[x][0];return x;}
	void delet(int x){
		splay(x,0);
		int y=findl(x),z=findr(x);
		splay(y,0);
		splay(z,y);
		c[z][0]=fa[x]=0;
		updata(z),updata(y);
	}
//};
string s[maxn],ch;
map<string,int> t;
void dfs(int x){
	if(c[x][0])dfs(c[x][0]);
	cout<<s[n-val[x].second]<<" "<<val[x].first<<endl;
	if(c[x][1])dfs(c[x][1]);
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	ios::sync_with_stdio(true);
	n=read();
	insert(make_pair(inf,-1));
	insert(make_pair(-inf,-1));
	up(i,1,n){
		char w;
		cin>>w;
		if(w==‘+‘){
			cin>>ch;
			s[i]=ch;
			int key;cin>>key;
			if(t.count(ch))delet(t[ch]);
			t[ch]=insert(make_pair(key,n-i));
			continue;
		}
		if(w==‘?‘){
			cin>>ch;
			if(ch[0]>=‘A‘&&ch[0]<=‘Z‘){
				int x=t[ch];
				splay(x,0);
				cout<<siz[c[x][1]]<<endl;
			}
			else {
				int k=0;
				up(j,0,ch.length()-1)
					k=k*10+ch[j]-‘0‘;
				int y=k;
				while(k-y<10){
					int x=n-val[getK(k)].second;
					if(x!=-1)cout<<s[x]<<" ";
					k++;
				}
				cout<<endl;
			}
			continue;
		}
		//dfs(rt);
		//cout<<endl;
	}
	return 0;
}

  

时间: 2024-12-15 07:15:44

[haoi2008]排名系统的相关文章

数据结构(Splay平衡树):HAOI2008 排名系统

[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入] 第一行是一个整数n(10<=n<=250000)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超

bzoj 1862/1056 [HAOI2008]排名系统

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 很恶心的 一道题,我也不晓得自己是第几次写这题了%>_<%. 写了两种方法,平衡树+哈希和平衡树+map.哈希函数是抄别人的.比较了一下还是哈希快一些. 题意很简单,就不说了. 具体思路是,平衡树维护排名,map建立姓名和分数一一对应的关系. 求rank时题意默认是越先提交得分排名越靠前(相同得分的条件下). 具体如下: 平衡树+map 1 #include<algorit

P4291 [HAOI2008]排名系统

传送门 怎么主要写的都是平衡树,这种查询排名,查询第 $K$ 大的操作直接权值线段树就行了 把读入的数据离散化一波,然后开个 $map$ 维护每个人最后一次插入时在线段树上的位置,直接线段树维护就完事了 查询排名就询问大于它的节点数量,查询第 $K$ 大直接线段树上二分 就是数据格式比较恶心,细节有点多 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #inc

bzoj1056 [HAOI2008]排名系统【updating】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1056 [题解] 就是一棵splay..吧? 一种用map,一种用hash表 本地测hash表跑的飞快,甚至比网络上只跑1s的还快,还是T了...qwq 查不出啊(逃 先晾在这吧,坑再说 map版本: # include <map> # include <stdio.h> # include <string.h> # include <iostream>

【pb_ds】bzoj1056 [HAOI2008]排名系统/bzoj1862 [Zjoi2006]GameZ游戏排名系统

STL裸题,线下AC,bzoj无限RE ing…… 1 #include<cstdio> 2 #include<cctype> 3 #include<iostream> 4 #include<string> 5 #include<ext/pb_ds/assoc_container.hpp> 6 #include<ext/pb_ds/tree_policy.hpp> 7 using namespace std; 8 using name

HNOI2008 and ZJOI2006 排名系统

1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1311  Solved: 337[Submit][Status] Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. Input 第一行是一个整数n(n

【HAOI2008】排名系统

[题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入格式] 第一行是一个整数n(n>=10)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超过10个字符.Score为最多8位的正整数.

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 Splay

Splay的基本操作,比较繁琐..... 有个一坑点,sorce会超int 1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 913  Solved: 343 [Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此