【洛谷 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\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...
随机推荐
- SQL 语句(增删改查)
一.增:有4种方法1.使用insert插入单行数据: --语法:insert [into] <表名> [列名] values <列值> 例:insert into Strden ...
- 图文详解 IntelliJ IDEA 15 创建 Maven 构建的 Java Web 项目(使用 Jetty 容器)
图文详解 IntelliJ IDEA 15 创建 maven 的 Web 项目 搭建 maven 项目结构 1.使用 IntelliJ IDEA 15 新建一个项目. 2.设置 GAV 坐标 3. ...
- Spring注解原理
一.注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解 ...
- c#对一个类的扩展
首先定义一个静态类,参数使用this约束并选择需要扩展的类,当然也可以 继续添加扩展是需要添加的参数 public static class StringExrprp { /// <summar ...
- 整合SSM框架应用
普通方式 新建spring模块时引入如下内容: 启用devtools插件(热部署插件) idea需要做如下配置 settings-build-compiler->勾选build project ...
- Expect the Expected UVA - 11427(概率dp)
题意: 每天晚上你都玩纸牌,如果第一次就赢了,就高高兴兴的去睡觉,如果输了就继续玩.假如每盘游戏你获胜的概率都为p,每盘游戏输赢独立.如果当晚你获胜的局数的比例严格大于p时才停止,而且每天晚上最多只能 ...
- Spring Batch @SpringBatchTest 注解
Spring Batch 提供了一些非常有用的工具类(例如 JobLauncherTestUtils 和 JobRepositoryTestUtils)和测试执行监听器(StepScopeTestEx ...
- JDBC连接SQL Server
下载jdbc驱动包 下载地址,我下载的是exe版本的,其实是格自解压包.下载完毕之后,双击运行,会解压在当前目录下. Microsoft SQL Server JDBC Driver 3.0\sqlj ...
- BZOJ2595 [Wc2008]游览计划 【状压dp + 最短路】
题目链接 BZOJ2595 题解 著名的斯坦纳树问题 设\(f[i][j][s]\)表示点\((i,j)\)与景点联通状况为\(s\)的最小志愿者数 设\(val[i][j]\)为\((i,j)\)需 ...
- linux内核分析第3章&第18章读书笔记
linux内核分析第3章&第18章读书笔记 第三章 进程管理 进程:处于执行期的程序(目标码存放在某种存储介质上) 包含资源:可执行程序代码,打开的文件,挂起的信号,内核内部数据,处理器状态, ...