什么毒瘤......

题意:模拟一棵单旋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. C# winform 设置WebBowser 内核版本

    一种是在网页头部 用 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 使用当前浏览器最新 ...

  2. Spring-data-jpa 学习笔记(二)

            通过上一篇笔记的,我们掌握了SpringData的相关概念及简单的用法.但上一篇笔记主要讲的是Dao层接口直接继承Repository接口,然后再自己定义方法.主要阐述了自定义方法时的 ...

  3. 牛客练习赛44 B题 (思维)

    链接:https://ac.nowcoder.com/acm/contest/634/B 来源:牛客网 给出n条线段,第i条线段的长度为ai, 每次可以从第i条线段的j位置跳到第i + 1条线段的j+ ...

  4. PostgreSQL基础知识与基本操作索引页

    磨砺技术珠矶,践行数据之道,追求卓越价值 返回顶级页:PostgreSQL索引页 luckyjackgao@gmail.com 本页记录所有本人所写的PostgreSQL的基础知识和基本操作相关文摘和 ...

  5. SQLAlchemy 与 fask-SQLAlchemy 中的多表查询例子

    我们知道,<学生.课程.选课>,是一个典型的多对多关系. 现分别用 SQLAlchemy 与 fask-SQLAlchemy 实现. 声明:本人实测通过. 使用 SQLAlchemy fr ...

  6. WordPress留言本插件推荐

    WordPress不借助于任何插件也可以做个留言本,那就是建个 Page, 直接使用它的评论功能即可,而且给评论加上 Ajax 功能.WYSIWYG.引用.回复.留言分页等功能也可以做的很漂亮.但对于 ...

  7. 用Visual Studio2017写C++静态库

    造轮子是一件有趣的事情,VS是一个强大的工具,能胜任超大规模的工程,但是讲真,对不那么大的项目配置起来不是那么友好(网上的其他教程也一点都不友好Orz).这里就展示一下构建一个简单的静态库的正确姿势. ...

  8. ASP.NetCore2.0概览

      微软为了统一微软平台,造就了.netStandard,不管之前的Framework还是最新的.netCore都必须支持.netStandard标准来统一各个平台的开发api. 以下是之前的微软各个 ...

  9. Nginx安装负载均衡配置 fair check扩展

    前言 本文主要是针对Nginx安装.负载均衡配置,以及fair智能选举.check后端节点检查扩展功能如何扩展,进行讲解说明. fair模块: upstream-fair,“公平的”Nginx 负载均 ...

  10. Shell 基础 -- 流编辑器 sed 详解

    一.流编辑器 sed 与命令 sed Linux 中,常使用流编辑器 sed 进行文本替换工作.与常使用的交互式编辑器(如vim)不同,sed 编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多, ...