[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在区间内的前驱(前驱定义 ...
随机推荐
- ES6学习笔记(1)----let和const命令
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ let和const命令 let 总结1.声明变量基本使用方法与var 相同 不同点 a.在代 ...
- Spring data jpa中Query和@Query分别返回map结果集
引用: http://blog.csdn.net/yingxiake/article/details/51016234 http://blog.csdn.net/yingxiake/article/d ...
- win7电脑桌面壁纸曝光过高影响图标怎么办?亲测实用解决方法
现在用win7系统的人应该还是挺多的吧,虽然说windows家族已经升级到现在的win11了,相信大多数人家用的电脑系统还是win7吧,今天要讲的是一个壁纸曝光度过高的解决办法,虽然还不清楚为什么,但 ...
- 函数式编程:上线文、包裹、容器-我们可以将一个值用Context(上下文)包裹起来
Functor,即函子,是 Haskell 中普遍存在的.最基本的类型类.你可以用以下两种方式来理解 Functor: 它代表某种容器,该容器能够将某一函数应用到其每一个元素上. 它代表某种“可计算上 ...
- day23-2 __call__、__str__和__del__
目录 __call__ __str__ __del__ __call__ 对象后面加括号调用时,会自动触发执行 注:构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执 ...
- deallocvt - 释放未使用的虚拟终端
SYNOPSIS(总览) deallocvt [ N1 N2 ... ] DESCRIPTION(描述) 如果不指定参数, deallocvt 程序会释放所有未使用的虚拟终端的核心内存和数据结构. 如 ...
- 关于TreeView控件的TreeNodeCheckChanged事件无法回发处理
1.在后台设置属性 TreeView1.Attributes.Add("onclick", "postBackByObject()"); 2.在前台页面中间添加 ...
- AttributeError: 'list' object has no attribute 'extends' && list详解
拼写错误 是extend 而不是extends 出错demo: In [27]: c = [2,3] In [28]: c.extends([5]) ------------------------ ...
- json 存 window.localStorage.setItem('hideColums',hideArr);
onColumnSwitch:function(row, $element){ //JSON.parse() var showColumns=$('#table').bootstrapTable('g ...
- bat copy
@echo off regedit /s %~dp0regedit.reg //注册注册表xcopy "D: ...