什么毒瘤......

题意:模拟一棵单旋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. VB6 CHECK is run as admin privilege

    vb6 code: Private Declare Function IsUserAnAdmin Lib "Shell32" Alias "#680" () A ...

  2. 汇编 REPE/REPZ 指令,CMPSB指令

    知识点: REPE/REPZ 指令 CMPSB 指令 一.CMPSB //cmp //sub //SCASB//scasw//scasd cmp byte ptr [edi],al //对标志位的 ...

  3. 学习JAVA第一章的心得

    我抱着万分期待的心情开始了我第一天的JAVA学习课程,其实在第一开始的时候我对计算机行业便有很高地兴趣了.这主要归功于我真的从很小开始就就接触了电脑.进入学校以来,我就很期待老师会怎样教我们,会怎样带 ...

  4. R绘图 第四篇:绘制箱图(ggplot2)

    箱线图通过绘制观测数据的五数总括,即最小值.下四分位数.中位数.上四分位数以及最大值,描述了变量值的分布情况.箱线图能够显示出离群点(outlier),离群点也叫做异常值,通过箱线图能够很容易识别出数 ...

  5. Js_图片轮换

    本文介绍用javascript制作图片轮换效果,原理很简单,就是设置延时执行一个切换函数,函数里面是先设置下面的缩略图列表的白框样式,再设置上面大图的src属性,在IE中显示很正常,可是在FF中会有变 ...

  6. allegro对齐操作

    在placement  edit模式下 选中元件,右键对齐即可.

  7. mac10.12.6系统配置clion编写CMakeLists文件运行opencv3

    按照mac10.12.6系统使用cmake安装opencv3.3.0+opencv_contrib-3.3.0下载编译安装好了文件以后,装好clion编译器,新建C++可执行工程,编写代码 opecv ...

  8. 第五次Scrum meeting

    第五次Scrum meeting 会议内容: 连接方面:确定封装成json的文本格式,尽量在满足在线组和手机客户端两组的情况下,降低自身的难度 测试方面:进行新一轮测试,主要测试程序的稳定性和可靠性, ...

  9. Day Nine

    站立式会议 站立式会议内容总结 331 今天:学习plupload 遇到问题:无 明天:学习中文分词 442 今天:解决gradle以及项目计划页面的bug 遇到的问题:调用工具类以及配置gradle ...

  10. HDU 2020 绝对值排序

    http://acm.hdu.edu.cn/showproblem.php?pid=2020 Problem Description 输入n(n<=100)个整数,按照绝对值从大到小排序后输出. ...