关于如何写splay

这是bzoj1208 郁闷的出纳员

#include<iostream>
#define N 200000
#define abs(x) ((x) > 0? (x): -(x))
using namespace std;
int n;
int now, ans;
struct splay
{
int ch[2];
int fa, si;
int dt;
};
splay tr[N];
int root, tl;
int is_right(int t) {return (tr[tr[t].fa].ch[1] == t);}
void rotate(int t)
{
int k = is_right(t), b = tr[t].ch[!k], a = tr[t].fa, o = tr[a].fa;
tr[a].ch[k] = b; tr[t].ch[!k]=a; if (o) tr[o].ch[is_right(a)] = t; else root = t;
if (b) tr[b].fa = a; tr[a].fa = t; tr[t].fa = o;
tr[a].si = tr[tr[a].ch[0]].si + tr[tr[a].ch[1]].si + 1;
tr[t].si = tr[tr[t].ch[0]].si + tr[tr[t].ch[1]].si + 1;
}
void up(int t)
{
while ((root != t) && (root))
{
if (tr[t].fa == root) {rotate(t); break;}
int a = tr[t].fa;
if (is_right(t) == is_right(a)) rotate(a), rotate(t);
else rotate(t), rotate(t);
}
}
int ask_before(int d)
{
int q = 0;
for (int p = root; p; )
if (tr[p].dt <= d) {q = p; p = tr[p].ch[1];}
else p = tr[p].ch[0];
return q;
}
int ask_after(int d)
{
int q = 0;
for (int p = root; p; )
if (tr[p].dt >= d) {q = p; p = tr[p].ch[0];}
else p = tr[p].ch[1];
return q;
}
void insert(int d)
{
int p = 0;
tl++;
if (root)
{
for (p = root; tr[p].ch[d > tr[p].dt]; p = tr[p].ch[d > tr[p].dt]) tr[p].si++;
tr[p].ch[d > tr[p].dt] = tl;
}
else root = tl;
tr[tl].fa = p; tr[tl].si = 1; tr[tl].dt = d;
up(tl);
}
void dele(int t)
{
int pp = 0;
up(t);
if (tr[t].ch[0])
{
root = tr[t].ch[0]; tr[root].fa = 0;
for (pp = root; tr[pp].ch[1]; pp = tr[pp].ch[1]);
up(pp);
}
else if (tr[t].ch[1]) root = tr[t].ch[1];
else root = 0;
tr[pp].ch[1] = tr[t].ch[1]; tr[pp].si += tr[tr[t].ch[1]].si; tr[tr[t].ch[1]].fa = pp;
tr[t].ch[0] = 0; tr[t].ch[1] = 0; tr[t].dt = 0 ; tr[t].si = 0;
}
int main()
{
cin >> n;
for (int i=1; i<=n; ++i)
{
int a, b;
cin >> a >> b;
if (!root) now = a;
if (a == now)
{
insert(b);
}
else
{
int p1 = ask_before(b), p2 = ask_after(b);
if (!p1) ans += abs(tr[p2].dt - b), dele(p2);
else if (!p2) ans += abs(tr[p1].dt - b), dele(p1);
else if (abs(tr[p1].dt - b) <= abs(tr[p2].dt - b)) ans += abs(tr[p1].dt - b), dele(p1);
else ans += abs(tr[p2].dt - b), dele(p2);
}
ans %= 1000000;
}
cout << ans;
}

时间: 2024-10-30 01:57:33

关于如何写splay的相关文章

bzoj1251: 序列终结者 (splay)

splay可以用于维护序列,比如noi的维修序列,比如这道 发现当时splay没写总结,也没题解 然后重新写splay竟然耗了一个晚上 结果是因为max[0]没有附最小值!!血一样的教训 最后祭出inline大法才过,我的splay真的慢到吐血 {$inline on} {$M 1000000000,0,maxlongint} const //mm=maxlongint>>2; maxn=60000; var size,left,right,mark,fa,value,max:array[0.

【BZOJ3786】星系探索 DFS序+Splay

[BZOJ3786]星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. 我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c. 对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的.并且从星球a出发只

BZOJ_1588&amp;Codevs_1296_[HNOI2002]_营业额统计(Treap/Splay)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1588 给出每一天的营业值,求出之前的天当中与它相差最小的营业值与它的差的绝对值(第一天的差值为他本身),求和. 分析 比宠物收养所更裸,果然十几年前的题都是水吗...然而我只会做水题. 注意: 1.第一次写Splay的时候重复的元素直接跳过导致一直T,后来就先把这个值伸展上来再跳过,就过了,果然这种均摊的复杂度不是可以瞎玩的... 另外,不判重似乎慢不了多少... #include <cst

spoj 4487. Can you answer these queries VI splay 常数优化

4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations: Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval

Splay伸展树学习笔记

Splay伸展树 有篇Splay入门必看文章 —— CSDN链接 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 创造者:Daniel Sleator 和 Robert Tarjan 优点:每次查询会调整树的结构,使被查询频率高的条目更靠近树根. Tree Rotation 树的旋转是splay的基础,对于二叉查找树来说,树的旋转不破坏查找树的结构. Splaying Splaying是Splay Tree中的基本操作,为了让被查询的条目更接近树根,Splay Tree

codevs 1743 反转卡片 rope or splay

[codevs1743]反转卡片 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N=5的一种情况:3 4 2 1 5 接下来你需要按小A的要求反转卡片,使得左数第一张卡片上的数字是1.操作方法:令左数第一张卡片上的数是K,如果K=1则停止操作,否则将左数第1~K张卡片反转. 第一次(K=3)反转后得到:2 4 3 1 5 第二次(K=2)反转后得到:4 2

【学术篇】NOIP2017 d2t3 列队phalanx splay做法

我可去他的吧.... ==============先胡扯些什么的分割线================== 一道NOIP题我调了一晚上...(其实是因为昨晚没有找到调试的好方法来的说...) 曾经我以为我写完了然后全WA 0分 发现 2 1 2 1 1 1 1 这组数据能把我卡掉(我都不知道怎么过样例的)... 然后就开始调就精神崩溃就放弃治疗就划水就过去了一下午和一晚上... 今天我立(砾)志要完成这道题. 上luogu打卡 两个号(不要问我为啥两个号)分别: 然后说我调不出WA的题我就很绝望

二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东西 1.查询值 int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else retur

营业额统计(bzoj1588)

Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题.经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大