[BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)
至少BZOJ过了,其他的直接弃。
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)
最外层套一颗线段树,用来表示区间,线段树下面套个splay用来维护当前线段树节点的区间。
对于第二问可以二分,看看哪个数的排名为 k。
——代码
#include <iostream>
#include <cstring>
#include <cstdio>
#define root 1, 1, n
#define lson now << 1, l, mid
#define rson now << 1 | 1, mid + 1, r
#define ls son[now][0]
#define rs son[now][1]
#define debug puts("**************"); const int MAXN = , INF = ; int n, m, sz;
int seq[MAXN], rt[MAXN];
int f[MAXN], son[MAXN][], cnt[MAXN], key[MAXN], size[MAXN]; inline int read()
{
int f = , x = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int max(int x, int y)
{
return x > y ? x : y;
} inline int min(int x, int y)
{
return x < y ? x : y;
} inline void Splay_clear(int now)
{
f[now] = cnt[now] = key[now] = size[now] = ls = rs = ;
} inline void Splay_update(int now)
{
if(now)
{
size[now] = cnt[now];
if(ls) size[now] += size[ls];
if(rs) size[now] += size[rs];
}
} inline int Splay_get(int x)
{
return son[f[x]][] == x;
} inline void Splay_rotate(int x)
{
int old = f[x], oldf = f[old], wh = Splay_get(x); son[old][wh] = son[x][wh ^ ];
f[son[old][wh]] = old; son[x][wh ^ ] = old;
f[old] = x; if(oldf) son[oldf][son[oldf][] == old] = x;
f[x] = oldf; Splay_update(old);
Splay_update(x);
} inline void Splay_splay(int x)
{
for(int fa; fa = f[x]; Splay_rotate(x))
if(f[fa])
Splay_rotate(Splay_get(x) ^ Splay_get(fa) ? x : fa);
} inline void Splay_insert(int x, int k)
{
int now = rt[x], fa = ;
if(!rt[x])
{
rt[x] = ++sz;
key[sz] = k;
size[sz] = cnt[sz] = ;
return;
}
while()
{
if(k == key[now])
{
cnt[now]++;
Splay_update(now);
Splay_splay(now);
rt[x] = now;
return;
}
fa = now;
now = son[now][k > key[now]];
if(!now)
{
rt[x] = ++sz;
f[sz] = fa;
key[sz] = k;
size[sz] = cnt[sz] = ;
son[fa][k > key[fa]] = sz;
//Splay_update(fa);
Splay_splay(sz);
return;
}
}
} inline int Splay_findrank(int x, int k)
{
int now = rt[x], ans = ;
while()
{
if(!now) return ans;
if(key[now] == k) return ans + size[ls];
else if(key[now] < k)
{
ans += cnt[now] + size[ls];
now = rs;
}
else now = ls;
}
} inline int Splay_find(int x, int k)
{
int now = rt[x];
while()
{
if(key[now] > k) now = ls;
else if(key[now] < k) now = rs;
else
{
rt[x] = now;
Splay_splay(now);
return now;
}
}
} inline int Splay_pre(int x)
{
int now = son[rt[x]][];
while(rs) now = rs;
return now;
} inline int Splay_suc(int x)
{
int now = son[rt[x]][];
while(ls) now = ls;
return now;
} inline void Splay_del(int x)
{
int now = rt[x];
if(cnt[now] > )
{
cnt[now]--;
Splay_update(now);
return;
}
if(!ls && !rs)
{
rt[x] = ;
Splay_clear(now);
return;
}
if(!ls || !rs)
{
rt[x] = ls + rs;
f[rt[x]] = ;
Splay_clear(now);
return;
}
int pre = Splay_pre(x);
Splay_splay(pre);
rt[x] = pre;
son[pre][] = rs;
f[rs] = pre;
Splay_clear(now);
Splay_update(pre);
} inline int Splay_findpre(int x, int k)
{
int now = rt[x], ans = -INF;
while(now)
{
if(key[now] < k)
{
ans = max(ans, key[now]);
now = rs;
}
else now = ls;
}
return ans;
} inline int Splay_findsuc(int x, int k)
{
int now = rt[x], ans = INF;
while(now)
{
if(key[now] > k)
{
ans = min(ans, key[now]);
now = ls;
}
else now = rs;
}
return ans;
} inline void SegTree_insert(int x, int k, int now, int l, int r)
{
Splay_insert(now, k);
if(l == r) return;
int mid = (l + r) >> ;
if(x <= mid) SegTree_insert(x, k, lson);
else SegTree_insert(x, k, rson);
} inline int SegTree_askrank(int x, int y, int k, int now, int l, int r)
{
if(x <= l && r <= y) return Splay_findrank(now, k);
if(l > y || r < x) return ;
int mid = (l + r) >> ;
return SegTree_askrank(x, y, k, lson) + SegTree_askrank(x, y, k, rson);
} inline void SegTree_change(int x, int k, int now, int l, int r)
{
Splay_find(now, seq[x]);
Splay_del(now);
Splay_insert(now, k);
if(l == r) return;
int mid = (l + r) >> ;
if(x <= mid) SegTree_change(x, k, lson);
else SegTree_change(x, k, rson);
} inline int SegTree_findpre(int x, int y, int k, int now, int l, int r)
{
if(x <= l && r <= y) return Splay_findpre(now, k);
if(l > y || r < x) return -INF;
int mid = (l + r) >> ;
return max(SegTree_findpre(x, y, k, lson), SegTree_findpre(x, y, k, rson));
} inline int SegTree_findsuc(int x, int y, int k, int now, int l, int r)
{
if(x <= l && r <= y) return Splay_findsuc(now, k);
if(l > y || r < x) return INF;
int mid = (l + r) >> ;
return min(SegTree_findsuc(x, y, k, lson), SegTree_findsuc(x, y, k, rson));
} int main()
{
int i, opt, x, y, z, ans, h, t, mid, maxn = ;
n = read();
m = read();
for(i = ; i <= n; i++) seq[i] = read(), maxn = max(maxn, seq[i]), SegTree_insert(i, seq[i], root);
for(i = ; i <= m; i++)
{
opt = read();
switch(opt)
{
case :
{
x = read();
y = read();
z = read();
printf("%d\n", SegTree_askrank(x, y, z, root) + );
break;
}
case :
{
x = read();
y = read();
z = read();
h = , t = maxn;
while(h <= t)
{
mid = (h + t) >> ;
if(SegTree_askrank(x, y, mid, root) + <= z) h = mid + ;
else ans = mid, t = mid - ;
}
printf("%d\n", ans - );
break;
}
case :
{
x = read();
z = read();
SegTree_change(x, z, root);
seq[x] = z;
maxn = max(maxn, z);
break;
}
case :
{
x = read();
y = read();
z = read();
printf("%d\n", SegTree_findpre(x, y, z, root));
break;
}
case :
{
x = read();
y = read();
z = read();
printf("%d\n", SegTree_findsuc(x, y, z, root));
break;
}
}
}
return ;
}
[BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)的更多相关文章
- BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】
BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...
- 【BZOJ 3196】二逼平衡树 线段树套splay 模板题
我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- BZOJ3196:二逼平衡树(线段树套Splay)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...
- BZOJ - 3196 Tyvj 1730 二逼平衡树 (线段树套treap)
题目链接 区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的. (据说线段树套线段树.树状数组套线段树也能过?) ...
- [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...
- 【bzoj3196】Tyvj 1730 二逼平衡树 线段树套Treap
题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义 ...
随机推荐
- 题解报告:NYOJ #311完全背包(恰好装满)
描述: 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是w.求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大.本题 ...
- C# winform与Javascript的相互调用[转]
原文链接<html> <head> <meta http-equiv="Content-Language" content="zh-cn&q ...
- 224 Basic Calculator 基本计算器
实现一个基本的计算器来计算一个简单的字符串表达式. 字符串表达式可以包含左括号 ( ,右括号),加号+ ,减号 -,非负整数和空格 . 假定所给的表达式语句总是正确有效的. 例如: "1 + ...
- rsync常见错误
rsync使用时的常见问题: 错误1: rsync: read error: Connection reset by peer (104) rsync error: error in rsync pr ...
- sdut2355Binary Search Heap Construction
链接 捣鼓了一下午..按堆建树 写完交 返回TLE..数据不大 感觉不会超了 无奈拿了数据来看什么奇葩数据会超 发现数据跟我输出不一样 看了好久才明白理解错题意了 给出的字符串有两个标签 按前一个来建 ...
- hihocoder offer收割编程练习赛11 D 排队接水
思路: 莫队算法+树状数组. 莫队算法的基本思想是对大量要查询的区间进行离线处理,按照一定的顺序计算,来降低复杂度.概括来说,我们在知道了[l, r]的解,并且可以通过一个较低的复杂度推出[l - 1 ...
- 升级 Cocoapods 到1.2.0指定版本,降低版本及卸载
=====================升级版本=================== CocoaPods 1.1.0+ is required to build SnapKit 3.0.0+. 在 ...
- Python学习 Day 7 面向对象 类和实例 访问限制
面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程 ...
- Farseer.net轻量级开源框架说明及链接索引
Farseer.net是什么? 基于.net framework 4 开发的一系列解决方案. 完全开源在GitHub中托管.并发布到NuGet中. Farseer.Net由最初的关系数据库ORM框架后 ...
- Farseer.net轻量级ORM开源框架 V1.3版本升级消息
SHA-1: abca3b99801648fa23c7f4934de6c128f042cf47 * 提交新版本:V1.31.重构:FS.Mapping命名空间移到 FS.Core.Map中2.重构:对 ...