什么毒瘤......

题意:模拟一棵单旋splay,求每次插入,splay最值,删除最值的操作次数。

解:乍一看感觉很神,又因为是LCT题单上的,然后就折磨了我好久,最后跑去看题解...

居然是手玩找规律题!我疯了。

是这样的,因为它只会单旋,而且只会splay最值,手玩一下就发现整个树的形态不变......就是把一个节点拿上去当根了,然后它的子节点代替它的位置。

插入,根据普通splay插入可知它一定接在前驱/后继的下面。找到深度大的那个就行了。

具体来说,用一棵值域线段树维护每个权值的深度。同时还要记录根,fa,son,树中节点数...

线段树要支持区间加,单点修改,查询第k大,区间求和,单点查询等功能。

大力分类讨论,注意一波细节,然后就A了...

 #include <cstdio>
#include <algorithm> const int N = ; struct Node {
int f, x;
}node[N]; int tag[N * ], sum[N * ], fa[N], s[N][], X[N], temp; inline void pushdown(int o) {
if(tag[o]) {
tag[o << ] += tag[o];
tag[o << | ] += tag[o];
tag[o] = ;
}
return;
} int ask(int p, int l, int r, int o) {
if(l == r) {
if(!sum[o]) {
tag[o] = ;
}
return tag[o];
}
pushdown(o);
int mid = (l + r) >> ;
if(p <= mid) {
return ask(p, l, mid, o << );
}
else {
return ask(p, mid + , r, o << | );
}
} void change(int p, int v, int l, int r, int o) {
if(l == r) {
if(v == -) {
sum[o] = tag[o] = ;
}
else {
sum[o] = ;
tag[o] = v;
}
return;
}
pushdown(o);
int mid = (l + r) >> ;
if(p <= mid) {
change(p, v, l, mid, o << );
}
else {
change(p, v, mid + , r, o << | );
}
sum[o] = sum[o << ] + sum[o << | ];
return;
} int getK(int k, int l, int r, int o) {
if(l == r) {
return r;
}
int mid = (l + r) >> ;
if(k <= sum[o << ]) {
return getK(k, l, mid, o << );
}
else {
return getK(k - sum[o << ], mid + , r, o << | );
}
} int getSum(int L, int R, int l, int r, int o) {
if(L <= l && r <= R) {
return sum[o];
}
int mid = (l + r) >> , ans = ;
if(L <= mid) {
ans += getSum(L, R, l, mid, o << );
}
if(mid < R) {
ans += getSum(L, R, mid + , r, o << | );
}
return ans;
} void add(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
tag[o] += v;
return;
}
pushdown(o);
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, v, l, mid, o << );
}
if(mid < R) {
add(L, R, v, mid + , r, o << | );
}
return;
} int main() {
int q, f, x, siz = , rt;
scanf("%d", &q);
for(int i = ; i <= q; i++) {
scanf("%d", &node[i].f);
if(node[i].f == ) {
scanf("%d", &node[i].x);
X[++temp] = node[i].x;
}
}
std::sort(X + , X + temp + );
temp = std::unique(X + , X + temp + ) - X - ;
for(int i = ; i <= q; i++) {
f = node[i].f;
if(f == ) {
x = std::lower_bound(X + , X + temp + , node[i].x) - X;
int k = getSum(, x, , temp, ), d;
if(!siz) {
d = ;
rt = x;
}
else if(!k) {
int r = getK(, , temp, );
d = ask(r, , temp, ) + ;
fa[x] = r;
s[r][] = x;
}
else if(k == siz) {
int l = getK(siz, , temp, );
d = ask(l, , temp, ) + ;
fa[x] = l;
s[l][] = x;
}
else {
int l = getK(k, , temp, );
int r = getK(k + , , temp, );
int dl = ask(l, , temp, );
int dr = ask(r, , temp, );
if(dl > dr) {
d = dl + ;
fa[x] = l;
s[l][] = x;
}
else {
d = dr + ;
fa[x] = r;
s[r][] = x;
}
}
change(x, d, , temp, );
printf("%d\n", d);
siz++;
}
else if(f == ) { // splay small
x = getK(, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int r = fa[x];
if(s[x][]) {
fa[s[x][]] = r;
}
s[r][] = s[x][];
add(r, temp, , , temp, );
change(x, , , temp, );
fa[x] = ;
s[x][] = rt;
fa[rt] = x;
rt = x;
}
printf("%d\n", d);
}
else if(f == ) {
x = getK(siz, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int l = fa[x];
if(s[x][]) {
fa[s[x][]] = l;
}
s[l][] = s[x][];
add(, l, , , temp, );
change(x, , , temp, );
fa[x] = ;
s[x][] = rt;
fa[rt] = x;
rt = x;
}
printf("%d\n", d);
}
else if(f == ) {
x = getK(, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int r = fa[x];
if(s[x][]) {
fa[s[x][]] = r;
}
s[r][] = s[x][];
add(, r - , -, , temp, );
}
else {
add(, temp, -, , temp, );
rt = s[x][];
fa[s[x][]] = ;
}
change(x, -, , temp, );
printf("%d\n", d);
siz--;
}
else if(f == ) {
x = getK(siz, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int l = fa[x];
if(s[x][]) {
fa[s[x][]] = l;
}
s[l][] = s[x][];
add(l + , temp, -, , temp, );
}
else {
add(, temp, -, , temp, );
rt = s[x][];
fa[s[x][]] = ;
}
change(x, -, , temp, );
printf("%d\n", d);
siz--;
}
}
return ;
}

AC代码

洛谷P3721 单旋的更多相关文章

  1. 洛谷 P3721 - [AH2017/HNOI2017]单旋(LCT)

    洛谷题面传送门 终于调出来这道题了,写篇题解( 首先碰到这样的题我们肯定要考虑每种操作会对树的形态产生怎样的影响: 插入操作:对于 BST 有一个性质是,当你插入一个节点时,其在 BST 上的父亲肯定 ...

  2. 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)

    题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...

  3. 洛谷P3371单源最短路径SPFA算法

    SPFA同样是一种基于贪心的算法,看过之前一篇blog的读者应该可以发现,SPFA和堆优化版的Dijkstra如此的相似,没错,但SPFA有一优点是Dijkstra没有的,就是它可以处理负边的情况. ...

  4. 洛谷P3371单源最短路径Dijkstra堆优化版及优先队列杂谈

    其实堆优化版极其的简单,只要知道之前的Dijkstra怎么做,那么堆优化版就完全没有问题了. 在做之前,我们要先学会优先队列,来完成堆的任务,下面盘点了几种堆的表示方式. priority_queue ...

  5. 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)

    首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...

  6. 洛谷 P4779 单源最短路径(标准版) 题解

    题面 这道题就是标准的堆优化dijkstra: 注意堆优化的dijkstra在出队时判断vis,而不是在更新时判断vis #include <bits/stdc++.h> using na ...

  7. 洛谷3721 HNOI2017单旋(LCT+set+思维)

    这题难道不是spaly裸题吗? 言归正传QWQ 一看到这个题目,其实第一反应是很懵X的 从来没有见过类似的题目啊,什么\(spaly\),单旋.QWQ很懵逼啊 不过,我们可以注意到这么一件事情,就是我 ...

  8. P3721 [AH2017/HNOI2017]单旋

    题目:https://www.luogu.org/problemnew/show/P3721 手玩一下即可AC此题. 结论:插入x后,x要么会成为x的前驱的右儿子,要么成为x的后继的左儿子,这取决于它 ...

  9. 洛谷 P4779【模板】单源最短路径(标准版)

    洛谷 P4779[模板]单源最短路径(标准版) 题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 10 ...

随机推荐

  1. go语言之行--golang核武器goroutine调度原理、channel详解

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

  2. 20155204《网络对抗》Exp9 Web安全基础实践

    20155204<网络对抗>Exp9 Web安全基础实践 一.基础问题回答 SQL注入攻击原理,如何防御? 原理: SQL注入即是指web应用程序对用户输入数据的合法性没有判断,攻击者可以 ...

  3. [Zlib]_[初级]_[使用zlib库压缩和解压STL string]

    场景 1.一般在使用文本json传输数据, 数据量特别大时,传输的过程就特别耗时, 因为带宽或者socket的缓存是有限制的, 数据量越大, 传输时间就越长. 网站一般使用gzip来压缩成二进制. 说 ...

  4. 微信小程序选择并上传图片

      上传图片 API: wx.chooseImage() 和 wx.uploadFile() wx.chooseImage({ count: 1, // 默认9 sizeType: ['origina ...

  5. CMake与MSVC工程化实践

    CMake与MSVC工程化实践 CMake基础 cmake无疑是最流行的c++跨平台构建工具之一,关于cmake入门指南这里不再赘述,官方文档是最好的参考,这里通过一个例子简述构建一个工程常用的函数和 ...

  6. L2-031 深入虎穴(BFS)

    著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报.已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门.每一扇门背后或者是一个房间,或者又有很多条路,同样是每条 ...

  7. PHP学习 例外和错误处理

    <?phptry{ open_folder("C:\\book");}catch(Exception $ex) { echo 'Error Message:'.$ex-> ...

  8. 一份超全超详细的 ADB 用法大全

    http://blog.csdn.net/u010375364/article/details/52344120

  9. Daily Scrum NO.4

    工作概况 符美潇(PM) 昨日完成的工作 1.Daily Scrum.日常会议及日常工作的分配和查收. 2.解决并录入了一个严重的过滤器BUG,该BUG会导致获取子链接的严重异常. 3.在TFS上进行 ...

  10. 2-Fifteenth Scrum Meeting-20151215

    任务安排 成员 今日完成 明日任务 闫昊 修复bug  写完学习进度记录的数据库操作 唐彬 编写与服务器交互的代码  编写与服务器交互的代码 史烨轩 获取视频url   余帆 修复bug  本地路径的 ...