bzoj 1862/1056 [HAOI2008]排名系统
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862
很恶心的 一道题,我也不晓得自己是第几次写这题了%>_<%。
写了两种方法,平衡树+哈希和平衡树+map。哈希函数是抄别人的。比较了一下还是哈希快一些。
题意很简单,就不说了。
具体思路是,平衡树维护排名,map建立姓名和分数一一对应的关系。
求rank时题意默认是越先提交得分排名越靠前(相同得分的条件下)。
具体如下:
平衡树+map
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<map>
using std::min;
using std::map;
using std::string;
const int Max_N = ;
char src[Max_N][];
typedef char State[];
struct Node{
int v, s, t, id;
Node *ch[];
inline void set(int _v = , int _s = , int _t = , int _id = , Node *p = NULL){
ch[] = ch[] = p;
v = _v, s = _s, t = _t, id = _id;
}
inline void push_up(){
s = ch[]->s + ch[]->s + ;
}
inline int cmp(int _v, int _t) const{
if (v == _v){
return t == _t ? - : _t > t;
}
return v > _v;
}
};
struct SizeBalanceTree{
Node stack[Max_N];
Node *root, *null, *tail;
Node *store[Max_N];
int top;
void init(){
tail = &stack[];
null = tail++;
null->set();
root = null;
top = ;
}
inline Node *newNode(int v, int t, int id){
Node *p = null;
if (top) p = store[--top];
else p = tail++;
p->set(v, , t, id, null);
return p;
}
inline void rotate(Node* &x, int d){
Node *k = x->ch[!d];
x->ch[!d] = k->ch[d];
k->ch[d] = x;
k->s = x->s;
x->push_up();
x = k;
}
inline void Maintain(Node* &x, int d){
if (x->ch[d] == null) return;
if (x->ch[d]->ch[d]->s > x->ch[!d]->s){
rotate(x, !d);
} else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s){
rotate(x->ch[d], d), rotate(x, !d);
} else {
return;
}
Maintain(x, ), Maintain(x, );
}
inline void insert(Node* &x, int v, int t, int id){
if (x == null){
x = newNode(v, t, id);
return;
} else {
x->s++;
int d = x->cmp(v, t);
insert(x->ch[d], v, t, id);
x->push_up();
Maintain(x, d);
}
}
inline void del(Node* &x, int v, int t){
if (x == null) return;
x->s--;
int d = x->cmp(v, t);
if (- == d){
if (!x->ch[]->s || !x->ch[]->s){
store[top++] = x;
x = x->ch[]->s ? x->ch[] : x->ch[];
} else {
Node *ret = x->ch[];
for (; ret->ch[] != null; ret = ret->ch[]);
x->v = ret->v, x->t = ret->t, x->id = ret->id;
del(x->ch[], ret->v, ret->t);
}
} else {
del(x->ch[d], v, t);
}
if (x != null) x->push_up();
}
inline int find(Node *x, int v, int t){
int k = , cur = ;
for (; x != null;){
int d = x->cmp(v, t);
k = x->ch[]->s;
if (- == d) break;
else if (!d) x = x->ch[];
else cur += k + , x = x->ch[];
}
return cur + k + ;
}
inline int rank(Node *x, int k){
for (; x != null;){
int t = x->ch[]->s;
if (k == t + ) break;
else if (k <= t) x = x->ch[];
else k -= t + , x = x->ch[];
}
return x->id;
}
inline void insert(int v, int t, int id){
insert(root, v, t, id);
}
inline void del(int v, int t){
del(root, v, t);
}
inline int find(int v, int t){
return find(root, v, t);
}
inline int rank(int k){
return rank(root, k);
}
}sbt;
struct node{
int v, t, id;
node(){};
node(int _v, int _t, int _id) :v(_v), t(_t), id(_id){}
};
map<string, node > stri;
void gogo(char *s, int v, int t, int &tot){
string str(s);
if (stri.count(str) != ){
sbt.del(stri[str].v, stri[str].t);
stri[str].v = v, stri[str].t = t;
sbt.insert(v, t, stri[str].id);
return;
}
strcpy(src[++tot], s);
sbt.insert(v, t, tot);
node ret(v, t, tot);
stri[str] = ret;
}
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
sbt.init();
State s1, buf;
int n, v, tot = ;
scanf("%d\n", &n);
for (int i = ; i <= n; i++){
gets(buf);
if (buf[] == '+'){
sscanf(&buf[], "%s %d", s1, &v);
gogo(s1, v, i, tot);
} else if (buf[] == '?' && isalpha(buf[])){
sscanf(&buf[], "%s", s1);
printf("%d\n", sbt.find(stri[s1].v, stri[s1].t));
} else {
int ed;
sscanf(&buf[], "%d", &v);
ed = min(v + , tot);
for (int j = v; j <= ed; j++) {
printf("%s%c", src[sbt.rank(j)], j != ed ? ' ' : '\n');
}
}
}
return ;
}
平衡树+哈希
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<map>
using std::min;
using std::pair;
using std::string;
typedef char State[];
typedef unsigned long long ull;
const int Max_N = ;
struct Node{
int v, s, t, id;
Node *ch[];
inline void
set(int _v = , int _s = , int _t = , int _id = , Node *p = NULL){
ch[] = ch[] = p;
v = _v, s = _s, t = _t, id = _id;
}
inline void push_up(){
s = ch[]->s + ch[]->s + ;
}
inline int cmp(int _v, int _t) const{
if (v == _v){
return t == _t ? - : _t > t;
}
return v > _v;
}
};
struct SizeBalanceTree{
Node stack[Max_N];
Node *root, *null, *tail;
Node *store[Max_N];
int top;
void init(){
tail = &stack[];
null = tail++;
null->set();
root = null;
top = ;
}
inline Node *newNode(int v, int t, int id){
Node *p = null;
if (top) p = store[--top];
else p = tail++;
p->set(v, , t, id, null);
return p;
}
inline void rotate(Node* &x, int d){
Node *k = x->ch[!d];
x->ch[!d] = k->ch[d];
k->ch[d] = x;
k->s = x->s;
x->push_up();
x = k;
}
inline void Maintain(Node* &x, int d){
if (x->ch[d] == null) return;
if (x->ch[d]->ch[d]->s > x->ch[!d]->s){
rotate(x, !d);
} else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s){
rotate(x->ch[d], d), rotate(x, !d);
} else {
return;
}
Maintain(x, ), Maintain(x, );
}
inline void insert(Node* &x, int v, int t, int id){
if (x == null){
x = newNode(v, t, id);
return;
} else {
x->s++;
int d = x->cmp(v, t);
insert(x->ch[d], v, t, id);
x->push_up();
Maintain(x, d);
}
}
inline void del(Node* &x, int v, int t){
if (x == null) return;
x->s--;
int d = x->cmp(v, t);
if (- == d){
if (!x->ch[]->s || !x->ch[]->s){
store[top++] = x;
x = x->ch[]->s ? x->ch[] : x->ch[];
} else {
Node *ret = x->ch[];
for (; ret->ch[] != null; ret = ret->ch[]);
x->v = ret->v, x->t = ret->t, x->id = ret->id;
del(x->ch[], ret->v, ret->t);
}
} else {
del(x->ch[d], v, t);
}
if (x != null) x->push_up();
}
inline int find(Node *x, int v, int t){
int k = , cur = ;
for (; x != null;){
int d = x->cmp(v, t);
k = x->ch[]->s;
if (- == d) break;
else if (!d) x = x->ch[];
else cur += k + , x = x->ch[];
}
return cur + k + ;
}
inline int rank(Node *x, int k){
for (; x != null;){
int t = x->ch[]->s;
if (k == t + ) break;
else if (k <= t) x = x->ch[];
else k -= t + , x = x->ch[];
}
return x->id;
}
inline void insert(int v, int t, int id){
insert(root, v, t, id);
}
inline void del(int v, int t){
del(root, v, t);
}
inline int find(int v, int t){
return find(root, v, t);
}
inline int rank(int k){
return rank(root, k);
}
}sbt;
#define BASE 133
#define MOD 299997
#define MAXN 500000
int now[Max_N], _time[Max_N];
struct HashSet{
int head[MAXN];
int tot, next[MAXN];
ull hash[MAXN];
char src[Max_N][];
inline ull GetHash(char *s){
ull re = ;
while (*s != '\0') re = re * BASE + *s++;
return re;
}
inline int Insert(char *s) {
ull _hash = GetHash(s);
int x = _hash % MOD;
for (int i = head[x]; i; i = next[i]){
if (hash[i] == _hash) return i;
}
next[++tot] = head[x];
hash[tot] = _hash;
head[x] = tot;
strcpy(src[tot], s);
return tot;
}
}map;
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
int n, v;
sbt.init();
State s1, buf;
scanf("%d\n", &n);
for (int i = ; i <= n; i++){
gets(buf);
if (buf[] == '+'){
sscanf(&buf[], "%s %d", s1, &v);
int x = map.Insert(s1);
if (now[x]) sbt.del(now[x], _time[x]);
now[x] = v, _time[x] = i;
sbt.insert(now[x], _time[x], x);
} else if (buf[] == '?' && isalpha(buf[])){
sscanf(&buf[], "%s", s1);
int x = map.Insert(s1);
printf("%d\n", sbt.find(now[x], _time[x]));
} else {
int ed;
sscanf(&buf[], "%d", &v);
ed = min(v + , map.tot);
for (int j = v; j <= ed; j++) {
printf("%s%c", map.src[sbt.rank(j)], j != ed ? ' ' : '\n');
}
}
}
return ;
}
bzoj 1862/1056 [HAOI2008]排名系统的更多相关文章
- bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 502[Submit][Statu ...
- 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- 1056: [HAOI2008]排名系统 - BZOJ
Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务 ...
- bzoj 1862: [Zjoi2006]GameZ游戏排名系统 & bzoj 1056: [HAOI2008]排名系统
傻叉了一晚上,把t打成x,然后这题神奇在于输出一段数,不足的不用输出,一开始我的是直接找没有后面就退,然后这样会格式错误囧……然后最后zj的还卡了下空间,于是不用string就过了……string毁一 ...
- [BZOJ 1056][HAOI2008]排名系统
传送门 \(\color{green}{solution}\) \(fhq \_treap\)模板题. 对于 \(+\) 操作,如果当前人不存在,那么直接加入;如果存在,那么先将他删除,再加入.复杂度 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
- 【BZOJ1056】[HAOI2008]排名系统(Splay)
[BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...
- 数据结构(Splay平衡树):HAOI2008 排名系统
[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录 ...
- BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay
BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...
随机推荐
- Eclipse SVN冲突解决
基本原则是:每次提交前需要先和线上的对比,先把冲突解决掉,然后把线上的更新到本地,最后把本地的提交上去. 右键项目 -> Team -> 与资源库同步 在同步视图中选择Conflicts ...
- extern 相关
假如a.h中有 int a=10; t1.cpp和t2.cpp同时include "a.h"则编译不成功,因为a重复定义:如果 a.h中是 static int a=10;则可以, ...
- ionic localstorage
angular.module('locals',[]) .factory('ls', ['$window', function($window) { return { set: function(ke ...
- leetcode007. Reverse Integer
/* a good way to predict overflow * each time *10 must predict int overflow * not only the last time ...
- ct任务添加与中控机批量后台操作
ct 任务nohup sh ./bin/start.sh </dev/null >/dev/null 2>&1 & 中控机批量 for h in `get_hosts ...
- 浅谈JavaScript的事件响应
原文出处: Christian Heilmann 译文出处:Chajn Science 每当猴子们问我JavaScript和DOM里啥东西最牛逼时,我都会一巴掌打回去:卧槽还用问么当然是事件响应了 ...
- tostring格式化输出
C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...
- 基于s5pv210嵌入式linux使用其他动态、静态库文件程序的交叉编译
刚刚移植了sqlite3迫切想测试一些,结果将原来在ubuntu系统下写好且测试通过的程序,重新编译就报错,无法找到已定义的函数 这是由于没有使用库或者使用了错误的就.库造成的结果. 正确做法为: a ...
- 设计模式-适配器模式(Adapter)
简介: 适配器模式在我看来是最无聊的一种模式,因为他根本不是一种新的创意模式,而是一种不得已而为之的模式.就算不学适配器模式,在具体应用场景中也会自然而然的想到这种解决方案. 张三在英国留学时买了个笔 ...
- .NET如何从配置文件中获取连接字符串
一.设置配置文件 <configuration> <!--在configuration下创建一个connectionStrings--> <connectionStrin ...