【洛谷 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\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...
随机推荐
- (三)MySQL终极篇
1.索引 详细介绍:http://www.cnblogs.com/57rongjielong/p/8039452.html 索引是对数据库表中一个或多个列的值进行排序的结构.索引是经过某种算法优化过的 ...
- LR监控apache服务器
开启mod_status模块功能,在LR的controller中找到apache资源图双击并右键添加度量,如下图: 添加apache服务器IP地址.选择系统平台.添加需要监控的计数器即可进行 ...
- rabbitmq 配置用户信息
本文摘自:http://my.oschina.net/hncscwc/blog/262246 1. 用户管理 用户管理包括增加用户,删除用户,查看用户列表,修改用户密码. 相应的命令 (1) 新增一个 ...
- 用友 SAP 金蝶 季报
用友 2018Q3季报 营收:.42亿 营收收入同比增长:42.36% 净利润:.35万 净利润同比增长率:113.83% 销售毛利率:66.88% 销售净利率:19.29% 用友2017财年年报 营 ...
- ViewPager、Fragment、Matrix综合使用实现Tab滑页效果
原文地址:http://www.cnblogs.com/kross/p/3372987.html 我们实现一个上面是一个可以左右滑动的页面,下面是三个可点击切换的tab按钮,tab按钮上还有一个激活条 ...
- Android性能测试工具:Emmagee介绍
简介 Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资源的性能测试小工具.该工具的优势在于如同windows系统性能监视器类似,它提供的是数据采集的功能,而行为则基于用户真实 ...
- 【Python】Python发展历史
起源 Python的作者,Guido von Rossum,荷兰人.1982年,Guido从阿姆斯特丹大学获得了数学和计算机硕士学位.然而,尽管他算得上是一位数学家,但他更加享受计算机带来的乐趣.用他 ...
- SWERC2015-I Text Processor
题意 给一个长度为\(n\)的字符串\(s\),再给定一个\(w\),问对于所有的\(i\in [1,n-w+1]\),\(s[i..i+w-1]\)有多少个不同字串.\(n,w\le 10^5\). ...
- [BZOJ4553][HEOI2016]序列 CDQ分治
4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec Memory Limit: 128 MB Description 佳媛姐姐过生日的时候,她的小伙 ...
- DataTable 转换 DataSet
DataTable dt = resuylt.Copy(); var dsR = new DataSet(); ds.Tables.Add(dt);