【洛谷 P4291】 [HAOI2008]排名系统(Splay,Trie)
题目链接
不是双倍经验我会去\(debug\)一上午?
一开始我是用的\(map+string\),跑的太慢了,T了4个点。
后来我手写了\(string\),重载了小于号,依然用的\(map\),T了2个点。
然后我加入各种卡常,发现没有用。
\(\cdots\)
然后我把手写\(string\)改成字符串哈希,依然用\(map\)存,还是\(T\)了2个点。
然后继续各种优化,没有用。
然后去看\(yyb\)聚聚的题解,原来可以每操作几百次随机\(Splay\)一下来保证树的随机性,只\(T\)了一个点了。
我去\(BZOJ\)离线题库上把这题数据下载下来,我觉得应该是最大的那个极限数据\(n=250000\)的点T了。
于是开文件本机上了试了下,跑了\(1.03-1.2s\)之间。
然后我疯狂改随机数种子,发现根本没什么用。
\(\cdots\)
后来又把\(map+\)字符串哈希改成了字典树,跑的飞快
最大的点本机\(0.7s\)左右,没理由跑不过啊
但交到洛谷上还是T
交到BZOJ上还是T
交到CJOJ上还是T
交到CodeVS上还是T
诶,CodeVS上显示TLE的点,\(n=130000\)
???????
于是找到\(BZOJ\)数据里的那个点,woc
原来有人的分数超过了\(999999999\),也就是我设的\(INF\),也就是\(Splay\)中2个虚点的值。
\(\cdots\)
直接超过了,这也太猛了。
然后虚点不是最大了,\(GG\)了。
看来\(INF\)还是要写成\(2147483647\)啊。
果然,改了\(INF\)后跑的飞快,总共才跑了\(479ms\)
吊打pbds
突然发现\(Splay\)好容易写
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <map>
#pragma GCC optimize(2)
using namespace std;
const int MAXN = 250010;
inline int read(){
int s = 0;
char ch = getchar();
while(ch < '0' || ch > '9')ch = getchar();
while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
struct info{
int val, id;
int operator > (const info A) const{
return val == A.val ? id < A.id : val > A.val;
}
};
struct splay{
info val;
int size, ch[2], fa;
}t[MAXN];
int root, num, T;
struct Trie{
int val;
Trie *ch[26];
Trie(){ for(int i = 0; i < 26; ++i) ch[i] = NULL; val = 0; }
}rt;
int Insert(char *s, int pos){
int len = strlen(s);
Trie *u = &rt;
for(int i = 0; i < len; ++i){
if(u->ch[s[i] - 'A'] == NULL) u->ch[s[i] - 'A'] = new Trie();
u = u->ch[s[i] - 'A'];
}
if(u->val) return u->val;
u->val = pos;
return 0;
}
inline void pushup(int x){
t[x].size = t[t[x].ch[0]].size + t[t[x].ch[1]].size + 1;
}
inline void rotate(int x){
int y = t[x].fa, z = t[y].fa, k = t[y].ch[1] == x;
t[y].ch[k] = t[x].ch[k ^ 1]; t[t[x].ch[k ^ 1]].fa = y;
t[y].fa = x; t[x].ch[k ^ 1] = y;
t[x].fa = z; t[z].ch[t[z].ch[1] == y] = x;
pushup(y); pushup(x);
}
inline void Splay(int x, int goal){
int y, z;
while(t[x].fa != goal){
y = t[x].fa; z = t[y].fa;
if(z != goal) rotate((t[y].ch[1] == x) ^ (t[z].ch[1] == y) ? x : y);
rotate(x);
}
if(!goal) root = x;
}
inline int insert(info x, int num){
if(!root){ root = num; t[root].val = x; t[root].size = 1; return root; }
int u = root, fa = 0;
while(u){ fa = u; u = t[u].ch[x > t[u].val]; }
int id = num; t[id].val = x; t[id].size = 1; t[id].fa = fa; if(fa) t[fa].ch[x > t[fa].val] = id;
Splay(id, 0);
return id;
}
int limit, tmp, Time;
void find(int x){
int u = root;
while(233){
if(t[t[u].ch[0]].size == x - 1) break;
if(t[t[u].ch[0]].size >= x) u = t[u].ch[0];
else x -= t[t[u].ch[0]].size + 1, u = t[u].ch[1];
}
Splay(u, 0);
}
char ch, name[MAXN][12];
int len[MAXN];
void dfs(int x){
if(!limit) return;
if(t[x].ch[1]) dfs(t[x].ch[1]);
if(!limit) return;
for(int i = 0; i < len[x]; ++i)
putchar(name[x][i]);
putchar(' ');
--limit;
if(t[x].ch[0]) dfs(t[x].ch[0]);
}
int next(int x, int mode){
Splay(x, 0);
int u = t[root].ch[mode];
while(t[u].ch[!mode]) u = t[u].ch[!mode];
return u;
}
char s[12];
int pq;
int main(){
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
T = read(); insert((info){ -2147483646, 9999999 }, ++num); insert((info){ 2147483646, -1 }, ++num);
while(T--){
ch = getchar();
while(ch != '+' && ch != '?') ch = getchar();
if(ch == '+'){
scanf("%s", s);
if(pq = Insert(s, num + 1)){
int l = next(pq, 0), r = next(pq, 1);
Splay(l, 0);
Splay(r, l);
t[t[root].ch[1]].ch[0] = 0;
Splay(t[root].ch[1], 0);
insert((info){ read(), ++Time }, pq);
}
else{
insert((info){read(), ++Time}, ++num);
memcpy(name[num], s, sizeof s);
len[num] = strlen(name[num]);
}
}
if(ch == '?'){
ch = getchar();
if(ch >= '0' && ch <= '9'){
tmp = 0;
while(ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
find(num - tmp);
for(int i = 0; i < len[root]; ++i)
putchar(name[root][i]);
putchar(' '); limit = 9;
if(t[root].ch[0]) dfs(t[root].ch[0]);
printf("\n");
}
else{
int p = 0;
while(ch >= 'A' && ch <= 'Z'){ s[p++] = ch; ch = getchar(); }
for(int i = p; i < 12; ++i) s[i] = 0;
Splay(Insert(s, 233), 0);
printf("%d\n", t[t[root].ch[1]].size);
}
}
if(T % 200 == 0) Splay(rand() % num + 1, 0);
}
return 0;
}
【洛谷 P4291】 [HAOI2008]排名系统(Splay,Trie)的更多相关文章
- [洛谷P4291][HAOI2008]排名系统
题目大意:三种操作: $+Name\;Socore:$上传最新得分记录,把以前的记录删除. $?Name:$ 查询玩家排名.如果两个玩家的得分相同,则先得到该得分的玩家排在前面. $?Index:$ ...
- 2021.12.07 P4291 [HAOI2008]排名系统(Treap)
2021.12.07 P4291 [HAOI2008]排名系统(Treap) https://www.luogu.com.cn/problem/P4291 双倍经验: https://www.luog ...
- P4291 [HAOI2008]排名系统
题目描述 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回 ...
- 【BZOJ1056】[HAOI2008]排名系统(Splay)
[BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...
- 数据结构(Splay平衡树):HAOI2008 排名系统
[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
- BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay
BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...
- bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 502[Submit][Statu ...
- [洛谷日报第62期]Splay简易教程 (转载)
本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...
- 洛谷 P4290 [HAOI2008]玩具取名
传送门 思路 博客半年没更新了,来更新个博文吧 在\(dsr\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...
随机推荐
- Varnish是一款高性能的开源HTTP加速器
如何衡量缓存系统的优劣性 1:缓存命中率: 在memcached服务器中,get_hits的值表示缓存命中的次数,get_misses的值表示没有命中的次数,那么命中率的计算公式就是:命中率=get_ ...
- springmvc值传递
1.页面向后台传值 A.HttpServletRequest方式: package com.rong.controller; import javax.annotation.Resource; imp ...
- 复利计算C语言转java的相关代码
static void principal()// 计算本金 { int N, m; double i, F, P; System.out.printf("复利终值:"); F = ...
- Jmeter 快速入门--简单的http压测
1.添加线程组 打开jmeter主窗口后,选择左侧树形结构里的"测试计划",然后右键选择添加,选择"threads(users)",选择"线程组&qu ...
- 转 maven3常用命令、java项目搭建、web项目搭建详细图解
转自地址:http://blog.csdn.net/edward0830ly/article/details/8748986 ------------------------------maven3常 ...
- 图文详解 IntelliJ IDEA 15 创建普通 Java Web 项目
第 1 部分:新建一个 Java Web Application 项目 File -> New -> Project…,请选择 Java EE 这个模块下的 Web Application ...
- Cobbler环境搭建
Cobbler服务器系统: CentOS 6.6 64位Cobbler版本: cobbler-2.6.11IP地址:192.168.166.136 1.安装epel库 rpm -ivh http:// ...
- (转)关于ActiveMQ的配置
目前常用的消息队列组建无非就是MSMQ和ActiveMQ,至于他们的异同,这里不想做过多的比较.简单来说,MSMQ内置于微软操作系统之中,在部署上包含一个隐性条件:Server需要是微软操作系统.(对 ...
- javascript与python的比较
1:javascript与python大小写皆敏感 2:javascript使用{}来组织代码块,与大部分语言相同 python使用缩进来组织代码块,与大部分语言不同,请务必遵守约定俗成的习惯,坚持 ...
- 【操作系统、UNIX环境编程】进程间通信
多个进程可以共享系统中的各种资源,但其中许多资源一次只能为一个进程使用,我们把一次仅允许一个进程使用的资源称为临界资源,许多物理设备都属于临界资源,如打印机等. Linux下进程间通信有如下几种方式: ...