题意

题目链接

Sol

这题好毒瘤啊。。

首先要观察到几个性质:

  1. 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值

  2. 上述操作对深度的影响相当于右子树不变,其他的位置-1

然后就可以做了,把询问离线之后离散化一下,建一棵权值线段树表示每个值对应的深度

同时用set维护出已经加入的值

每次先找到后继,看一下有没有左孩子,如果有的话说明前驱一定没有右孩子。

注意随时更新信息

复杂度\(O(nlogn)\)

#include<bits/stdc++.h>
#define Pair pair<LL, LL>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, opt[MAXN], val[MAXN], date[MAXN], cnt;
void DES() {
sort(date + 1, date + cnt + 1);
cnt = unique(date + 1, date + cnt + 1) - date - 1;
for(int i = 1; i <= M; i++) if(opt[i] == 1) val[i] = lower_bound(date + 1, date + cnt + 1, val[i]) - date;
}
set<int> s;
#define ls k << 1
#define rs k << 1 | 1
int add[MAXN], root, f[MAXN], ll[MAXN], rr[MAXN];
void ps(int k, int v) {
add[k] += (rr[k] - ll[k] + 1) * v;
f[k] += v;
}
void pushdown(int k) {
if(!f[k]) return ;
ps(ls, f[k]); ps(rs, f[k]);
f[k] = 0;
}
void update(int k) {
add[k] = add[ls] + add[rs];
}
void Build(int k, int ll, int rr) {
if(ll == rr) return ;
int mid = ll + rr >> 1;
Build(ls, ll, mid); Build(rs, mid + 1, rr);
}
void IntAdd(int k, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) {ps(k, v); return ;}
pushdown(k);
int mid = l + r >> 1;
if(ql <= mid) IntAdd(ls, l, mid, ql, qr, v);
if(qr > mid) IntAdd(rs, mid + 1, r, ql, qr, v);
update(k);
}
void Modify(int k, int l, int r, int p, int v) {
if(l == r) {add[k] = v; return ;}
int mid = l + r >> 1;
pushdown(k);
if(p <= mid) Modify(ls, l, mid, p, v);
else Modify(rs, mid + 1, r, p, v);
update(k);
}
int Query(int k, int l, int r, int p) {
if(l == r) return add[k];
int mid = l + r >> 1;
pushdown(k);
if(p <= mid) return Query(ls, l, mid, p);
else return Query(rs, mid + 1, r, p);
} #undef ls
#undef rs #define ls(x) ch[x][0]
#define rs(x) ch[x][1]
int ch[MAXN][2], fa[MAXN];
void connect(int x, int _fa, int tag) {
if(x == _fa || (_fa == M + 1)) return ;
ch[_fa][tag] = x;
fa[x] = _fa;
}
int insert(int v) {
if(s.empty()) {root = v; Modify(1, 1, M, v, 1); s.insert(v); fa[v] = M + 1; return 1;}
auto nxt = s.upper_bound(v);
if(nxt != s.end() && !ls(*nxt)) {
int pos = *nxt;
Modify(1, 1, M, v, Query(1, 1, M, pos) + 1);
connect(v, pos, 0);
} else {
nxt--; int pos = *nxt;
Modify(1, 1, M, v, Query(1, 1, M, pos) + 1);
connect(v, pos, 1);
}
s.insert(v);
return Query(1, 1, M, v);
}
int RotateMin() {
int mn = *s.begin(), v = Query(1, 1, M, mn);
IntAdd(1, 1, M, mn + 1, fa[mn] - 1, -1);
IntAdd(1, 1, M, 1, M, 1);
Modify(1, 1, M, mn, 1);
connect(rs(mn), fa[mn], 0);
connect(root, mn, 1);
root = mn; fa[root] = M + 1;
return v;
}
int RotateMax() {
auto it = s.end(); it--;
int mx = *it, v = Query(1, 1, M, mx);
IntAdd(1, 1, M, (fa[mx] == M + 1) ? 1 : fa[mx] + 1, mx - 1, -1);
IntAdd(1, 1, M, 1, M, 1);
Modify(1, 1, M, mx, 1);
connect(ls(mx), fa[mx], 1);
connect(root, mx, 0);
root = mx; fa[root] = M + 1;
return v;
}
int DeletMin() {
int v = RotateMin();
int mn = *s.begin(); fa[rs(mn)] = M + 1; root = rs(mn);
IntAdd(1, 1, M, 1, M, -1);
Modify(1, 1, M, mn, 0);
fa[mn] = rs(mn) = ls(mn) = 0;
s.erase(mn);
return v;
}
int DeletMax() {
int v = RotateMax();
auto it = s.end(); it--;
int mx = *it; fa[ls(mx)] = M + 1; root = ls(mx);
IntAdd(1, 1, M, 1, M, -1);
Modify(1, 1, M, mx, 0);
fa[mx] = ls(mx) = rs(mx) = 0;
s.erase(mx);
return v;
}
signed main() {
M = read();
for(int i = 1; i <= M; i++) {
opt[i] = read();
if(opt[i] == 1) val[i] = read(), date[++cnt] = val[i];
}
Build(1, 1, M);
DES();
for(int i = 1; i <= M; i++) {
if(opt[i] == 1) printf("%d\n", insert(val[i]));
else if(opt[i] == 2) printf("%d\n", RotateMin());
else if(opt[i] == 3) printf("%d\n", RotateMax());
else if(opt[i] == 4) printf("%d\n", DeletMin());
else printf("%d\n", DeletMax());
}
return 0;
}
/*
4
1 39877
1 76497
2
1 6377
*/

洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)的更多相关文章

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

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

  2. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  3. 【BZOJ4825】[Hnoi2017]单旋 线段树+set

    [BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...

  4. 【bzoj4825】[Hnoi2017]单旋 线段树+STL-set

    题目描述 H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能.有一天 ...

  5. P3721 [AH2017/HNOI2017]单旋

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

  6. BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)

    BZOJ LOJ 洛谷 这题不难啊,我怎么就那么傻,拿随便一个节点去模拟.. 我们只需要能够维护,将最小值或最大值转到根.模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\( ...

  7. luogu P3721 [AH2017/HNOI2017]单旋

    传送门 \(Spaly:\)??? 考虑在暴力模拟的基础上优化 如果要插入一个数,那么根据二叉查找树的性质,这个点一定插在他的前驱的右子树或者是后继的左子树,可以利用set维护当前树里面的数,方便查找 ...

  8. 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)

    题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...

  9. 洛谷 P3723 [AH2017/HNOI2017]礼物 解题报告

    P3723 [AH2017/HNOI2017]礼物 题目描述 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个 ...

随机推荐

  1. java数组-如何在一堆数据中使用数组!

    数组 1.类型一致的一组数据,其实相当于集合概念. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成.其中,每一个数据称作一个数组元素(item),每个数组元素可以通过一个下标/索引来 ...

  2. Python队列及在微信机器人中的应用

    本文来源于i春秋学院,未经允许严禁转载. 最近打算更新微信机器人,发现机器人的作者将代码改进了很多,但去掉了sqlite数据库,需要自己根据需求设计数据库,跟作者沟通得到的建议是为了防止消息并发导致数 ...

  3. fatal: protocol error: bad line length character: This

    昨晚尝试搭建一个Git服务器,在搭建好服务器后,在服务器创建了一个空项目,我在本地使用git clone 拉取项目时,报了fatal: protocol error: bad line length ...

  4. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

  5. javascript 小方块平移

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. LeetCode:114_Flatten Binary Tree to Linked List | 将一棵二叉树变成链表的形式 | Medium

    要求:Given a binary tree, flatten it to a linked list in-place.将二叉树转化为平坦序列的树.比如: 结题思路: 该题有个提示,转化后的树的序列 ...

  7. Python模块——PrettyTable 模块

    简介 PrettyTable 是python中的一个第三方库,可用来生成美观的ASCII格式的表格,十分实用. 安装 pip install prettytable 示例 从已有文件创建 CSV fr ...

  8. [EXP]McAfee ePO 5.9.1 - Registered Executable Local Access Bypass

    # Exploit Title: McAfee ePO 5.9.1 Registered Executable Local Access Bypass # Date: 2019-03-07 # Exp ...

  9. python 多环境共存 基础

    正在学习python 使用的是3.3 但是由于种种原因吧 还得使用python2.7 所以记录一下 如何安装2个版本 假设 在windows 下面安装的python 版本 和路径 如下 python ...

  10. springboot属性注入转化为对象

    第一种方式:用spel表达式解析 @Value("#{ T(com.alibaba.fastjson.JSON).parseObject('${train.purchase}')}" ...