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 排名系统通常要应付三种请求:上传 ...
随机推荐
- opecv轮廓匹配,可以用于去噪
一个跟轮廓相关的最常用到的功能是匹配两个轮廓.如果有两个轮廓,如何比较它们;或者如何比较一个轮廓和另一个抽象模板. 矩 比较两个轮廓最简洁的方式是比较他们的轮廓矩.这里先简短介绍一个矩的含义.简单的说 ...
- [linux] 替换字符串
Linux下批量替换多个文件中的字符串的简单方法.用sed命令可以批量替换多个文件中的字符串. 命令如下:sed -i “s/原字符串/新字符串/g” `grep 原字符串 -rl 所在目录` 例如: ...
- 华为OJ平台——尼科彻斯定理
题目描述: 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和. 例如: 1^3=1 2^3=3+5 3^3=7+9+11 4^3=13+15+17+19 输入 输入一个int整数 ...
- CLRS:Insert sort in in c
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>#define ...
- PAT1013
#include<cstdio>#include<cstring>#include<vector>using namespace std;const int max ...
- js DOM的几个常用方法
<div id="div1">这是个测试</div> <p </p> <p </p> //js DOM的几个常用方法 / ...
- 多行文字垂直居中(完美兼容chrome firefox IE6 7 8 9)
在说到这个问题的时候,也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗?即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊!所以在这里我还要啰嗦两句,CSS中 ...
- OpenGL函数解析之glLoadIdentity()
函数原型:void glLoadIdentity(void) 函数说明:调用glLoadIdentity()函数可以恢复初始坐标系,用一个4x4的单位矩阵来代替当前矩阵,实际上就是对当前矩阵进行初始化 ...
- Loadrunner:集合点(Rendezvous)
集合点:等到特定的用户数后再一起执行某个操作,比如一起登录.一起发信,一般情况下使用不到集合点,不过,订票系统或者促销类需要用到,比如说某个促销品的促销时间在8点到8点30,这样的话,就可能出现在8点 ...
- Boost C++: 网络编程1
#include <iostream> #include <boost/asio.hpp> #include <boost/config/compiler/visualc ...