题意

题目链接

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. k8s docker集群搭建

    一.Kubernetes系列之介绍篇   •Kubernetes介绍 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器 ...

  2. Adobe Photoshop CC 2019画板背景色白底如何去掉?

    Adobe Photoshop CC 2019画板背景色白底切透明图片很不方便,有两种方法可以解决: 第一种方法: 新建文档的时候直接背景内容直接选择透明 若设计师提供的设计稿是白底也没关系,就是第二 ...

  3. CVE-2015-1641 Office类型混淆漏洞及shellcode分析

    作者:枕边月亮 原文来自:CVE-2015-1641 Office类型混淆漏洞及shellcode分析 0x1实验环境:Win7_32位,Office2007 0x2工具:Windbg,OD,火绒剑, ...

  4. ES6教程-字符串,函数的参数,了解函数的arguments对象,js面向对象,设计模式-单例模式,解构赋值

    前言 主要讲解了ES6对字符串的拓展,包括includes,startsWith和endsWith,另外增加了字符串模板. Start includes()是否包含 startsWith()以什么开头 ...

  5. jmeter获取cookies信息(配置)

    jmeter发送请求后,响应信息里获取不到cookies(实际上会返回一个cookies),解决方法: 在jmeter.properties里找到CookieManager.save.cookies, ...

  6. Introduction to CELP Coding

    Speex is based on CELP, which stands for Code Excited Linear Prediction. This section attempts to in ...

  7. Rip配置

    Rip配置 首先建立如图拓扑图 分别配置两台电脑的ip地址和子网掩码和网关.如图所示. 在router0上配置两个端口的IP以及子网掩码 在路由器router0上配置rip2协议.里面的no auto ...

  8. fidder显示 请求响应时间

    在顶部的工具栏找到 Rules->CustomRules,第一次打开会弹出提示要安装Fiddler Script 工具,选择 [否], 就会打开 CustomRules.js 文件. 在 cla ...

  9. 剑指offer【01】- 二维数组中的查找(Java)

    在经历了春招各大公司的笔试题和面试官的血虐之后,决定要刷一些算法题了,不然连面试机会都没有. 而应对笔试和面试,比较出名的就是剑指offer的题目和LeetCode的题目了.剑指offer应对面试中的 ...

  10. web自动化测试---web页面元素的定位

    selenium提供了很多用于定位元素的方法,首先我们自己需要知道元素有哪些属性,这就需要用到安装测试环境中firebug来定位 打开firefox浏览器,按下F12键,我们就可以看到如下图所示的界面 ...