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 排名系统通常要应付三种请求:上传 ...
随机推荐
- iOS copy&mutableCopy理解
Copy&mutableCopy 通过copy方法可以创建可变或不可变对象的不可变副本,通过mutableCopy可以创建可变或不可变对象的可变副本. 拷贝分为浅拷贝和深拷贝: 浅拷贝:指 ...
- Android开发如何去除标题栏title
虽然是一个小问题,今天遇到了,也就写下来吧.防止自己忘掉. 取消标题栏的方式有两种,一种是在代码添加,另一种是在AndroidManifest.xml里面添加. 1.在代码中实现:在此方法setCon ...
- 开源项目:DolphinPlayer
Dolphin Player是一款基于FFmpeg解码视频播放器,支持大多数的音频和视频格式. 项目主页:http://code.google.com/p/dolphin-player/ 源代码Git ...
- vyatta的fork开源版本
https://www.reddit.com/r/networking/comments/3dvwfy/who_here_is_using_vyos/ Vyatta came in two flavo ...
- import的用法
转自python学习笔记--模块和命名空间 模块(module)是Python中非常重要的一个概念,模块其实就一些函数和类的集合文件,它能实现一些相应的功能,当我们需要使用这些功能的时候,直接把相应的 ...
- php xml 互相转换
正好昨天才做过类似的需求……几行代码就可以搞定. 如果你使用 curl 获取的 xml data$xml = simplexml_load_string($data);$data['tk'] = js ...
- IE样式兼容写法
1.第一种写法 利用<!--[if lt IE 6/7/8/9/10/11]><![endif]-->,给每个html写一个class <!DOCTYPE html> ...
- dig out deledted chat messages
One of my friends asked me to do a favor for her. She said her friend deleted some important chat me ...
- Windows Phone 8 通过一个app启动另一个app
Winphone8 通过app启动第三方app需要被启动的app支持,具体操作步骤如下: 假设要通过PhoneApp2启动PhoneApp1 PhoneApp1端做的操作如下: 1.注册Protoco ...
- 添加删除程序无法安装IIS 提示没法加载模块
添加删除程序无法安装IIS 提示没法加载模块 安装iis的时候提示 解决办法:依次是 属性--高级--系统变量--Path 变量值是:%SystemRoot%\system32;%SystemRoo ...