题目链接

不是双倍经验我会去\(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)的更多相关文章

  1. [洛谷P4291][HAOI2008]排名系统

    题目大意:三种操作: $+Name\;Socore:$上传最新得分记录,把以前的记录删除. $?Name:$ 查询玩家排名.如果两个玩家的得分相同,则先得到该得分的玩家排在前面. $?Index:$ ...

  2. 2021.12.07 P4291 [HAOI2008]排名系统(Treap)

    2021.12.07 P4291 [HAOI2008]排名系统(Treap) https://www.luogu.com.cn/problem/P4291 双倍经验: https://www.luog ...

  3. P4291 [HAOI2008]排名系统

    题目描述 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回 ...

  4. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

  5. 数据结构(Splay平衡树):HAOI2008 排名系统

    [HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录 ...

  6. [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2487  Solved: 711[Submit][Statu ...

  7. BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay

    BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...

  8. bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 502[Submit][Statu ...

  9. [洛谷日报第62期]Splay简易教程 (转载)

    本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...

  10. 洛谷 P4290 [HAOI2008]玩具取名

    传送门 思路 博客半年没更新了,来更新个博文吧 在\(dsr\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...

随机推荐

  1. virsh 命令行管理虚拟机

    重用命令和选项 1:查看运行的虚拟机 virsh list   2:查看所有的虚拟机(关闭和运行的虚拟机) virsh list --all   3:连接虚拟机 virsh console +域名(虚 ...

  2. oracle & 的用法!

    /*select * from emp_bak where deptno = &"Department number" order by ename; select * f ...

  3. ViewPager、Fragment、Matrix综合使用实现Tab滑页效果

    原文地址:http://www.cnblogs.com/kross/p/3372987.html 我们实现一个上面是一个可以左右滑动的页面,下面是三个可点击切换的tab按钮,tab按钮上还有一个激活条 ...

  4. hibernate.cfg.xml案例

    一.概念. hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.既然学习Hibernate那么第 ...

  5. phpMyadmin导入导出数据中出现的错误处理

    1 2

  6. 第129天:node.js安装方法

    node.js安装方法 第一步:双击node.js安装包开始安装,注意64位和32位,按照自己的进行安装 第二步:在安装过程中一直选择next,在选择安装目录时,大多数默认安装在C盘,我安装在了D盘, ...

  7. windows上配置连接git

    Windows7上安装Git   我首先是百度到了这个网站:https://git-scm.com/download/win 这个网站上有下载链接,你可以根据你的系统选择不同的下载链接,我的是Win7 ...

  8. VS的IISExpress配置通过IP访问程序

    打开C:\Users\用户\Documents\IISExpress\config\applicationhost.config 获取本地VS项目运行起来的端口,比如 然后在文本里搜索  24395 ...

  9. CF449,急需提高姿势水平

    这可能是我第1场只出1题的div1? A 鬼畜题? 我的dev没有字符统计功能,于是只好扔到notepad++上.数错好几次.题目本身没什么特别的地方. B 当时一直没想出来QAQ 题目中说m> ...

  10. 前端基础----JavaScript基础

    一.JavaScript概述 1,JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEa ...