4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap
国际惯例的题面:
这种维护排序序列,严格大于的进行操作的题都很套路......
我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好。
显然第一个区间的不会变化,第二个区间的会被平移进第一个区间,第三个区间的相对大小不会变化。
于是我们直接把第二个区间拆了重构,一个一个插入第一个区间即可。因为每次这样做最少减半,所以每个元素只会被重构log次,复杂度nlog^2n。
这种按照值域分离区间的操作,非旋转treap实现起来是最简单的......
然而第一次写非旋转treap还是出了一点问题,注意它的插入是通过按照值域分裂,新建点,再进行两次合并实现的。直接插入复杂度不对。
另外区间值域存在重合的情况两个treap不能直接合并......
我写的判定size的版本复杂度好像不对(不如暴力快?),于是只好预先生成fix值。
代码:
#include<cstdio>
#include<algorithm>
#include<cstdlib>
const int maxn=1e5+1e2; typedef std::pair<int,int> pii;
__inline pii mp(const int &x,const int &y) { return std::make_pair(x,y); } int seq[maxn],sql;
int stk[maxn],top; struct Treap {
int lson[maxn],rson[maxn],lazy[maxn],val[maxn],siz[maxn],fix[maxn],cnt; inline void init(int n) {
for(int i=;i<=n;i++) fix[i] = i;
std::random_shuffle(fix+,fix++n);
}
inline void apply(int pos,int x) {
if(pos) lazy[pos] += x , val[pos] -= x;
}
inline void push(int pos) {
if( lazy[pos] ) apply(lson[pos],lazy[pos]) , apply(rson[pos],lazy[pos]) , lazy[pos] = ;
}
inline void maintain(int pos) {
siz[pos] = siz[lson[pos]] + siz[rson[pos]] + ;
} inline pii split(int pos,int dv) { // left is <= , right is > .
if( !pos ) return mp(,);
push(pos);
if( dv < val[pos] ) {
pii spl = split(lson[pos],dv);
lson[pos] = spl.second , maintain(pos);
return mp(spl.first,pos);
} else {
pii spr = split(rson[pos],dv);
rson[pos] = spr.first , maintain(pos);
return mp(pos,spr.second);
}
}
inline int merge(int x,int y) {
if( !x || !y ) return x | y;
push(x) , push(y);
if( val[x] > val[y] ) std::swap(x,y);
if( fix[x] > fix[y] ) { // siz[x] is bigger .
lson[y] = merge(lson[y],x) , maintain(y);
return y;
} else {
rson[x] = merge(rson[x],y) , maintain(x);
return x;
}
}
inline void dfs(int pos) {
if( !pos ) return;
seq[++sql] = val[pos] , push(pos);
dfs(lson[pos]) , dfs(rson[pos]);
lson[pos] = rson[pos] = siz[pos] = , stk[++top] = pos;
}
inline int kth(int pos,int k) { // return the kth value .
if( k == siz[lson[pos]] + ) return val[pos];
return push(pos) , k <= siz[lson[pos]] ? kth(lson[pos],k) : kth(rson[pos],k-siz[lson[pos]]-);
}
inline void insert(int &root,int x) {
val[++cnt] = x , siz[cnt] = ;
pii sp = split(root,x);
root = merge(sp.first,cnt) , root = merge(root,sp.second);
}
inline void reinsert(int &root,int x) {
int cur = stk[top--];
val[cur] = x , siz[cur] = ;
pii sp = split(root,x);
root = merge(sp.first,cur) , root = merge(root,sp.second);
} }tp; int main() {
static int n,m,root,rtl,rtm,rtr;
scanf("%d%d",&n,&m) , tp.init(n);
for(int i=,t;i<=n;i++) scanf("%d",&t) , tp.insert(root,t);
for(int i=,o,x;i<=m;i++) {
scanf("%d%d",&o,&x);
if( o == ) printf("%d\n",tp.kth(root,x));
else if( o == ) {
pii sp = tp.split(root,x);
rtl = sp.first , sp = tp.split(sp.second,x<<);
rtm = sp.first , rtr = sp.second;
sql = , tp.dfs(rtm) , tp.apply(rtr,x);
for(int i=;i<=sql;i++) tp.reinsert(rtl,seq[i]-x);
root = tp.merge(rtl,rtr);
}
}
return ;
}
Thupc被拒了好气啊!我们队可是有yzy大爷的!(即使这样都被拒了,一看就是我太菜了)
ありのままでいればいつも
只要坚守自我维持现状
あるべき私かここにいると
自己希望成为的样貌就存在于此
信じてまた 新しい夢を
不要放弃希望 崭新的梦想
精一杯描き出せばいい
再次奋力地去描绘就好
そう気づき始めたよ私
是啊 而我开始意识到
みんなとただ笑ってる未来を
大家单纯地绽放笑容的未来
夢見て
诚心盼望
4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap的更多相关文章
- BZOJ 4923: [Lydsy1706月赛]K小值查询 Splay + 思维
Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...
- [BZOJ 4923][Lydsy1706月赛]K小值查询
传送门 势能分析平衡树,splay或treap都可以 放个指针版的就跑 #include <bits/stdc++.h> using namespace std; #define rep( ...
- [BZ4923][Lydsy1706月赛]K小值查询
K小值查询 题面 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. Input ...
- BZOJ4923:[Lydsy1706月赛]K小值查询(Splay)
Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...
- BZOJ4923 [Lydsy1706月赛]K小值查询
题意 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. \(n \leq 10 ...
- BZOJ3224普通平衡树——非旋转treap
题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- [bzoj3065] 带插入区间第k小值 [重量平衡树套线段树]
题面 传送门 思路 发现强制在线了...... 本来可以树套树解决的问题,现在外层不能使用线段树了,拿什么替代呢? 我们需要一种支持单点插入.下套数据结构.数据结构上传合并复杂度最多单log,不能旋转 ...
- [bzoj4923]K小值查询
来自FallDream的博客,未经允许,请勿转载,谢谢. 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有 ...
随机推荐
- SLAM学习资料汇总
转自 http://www.cnblogs.com/wenhust/ 书籍: 1.必读经典 Thrun S, Burgard W, Fox D. <Probabilistic robotic ...
- AutoMapper中用户自定义转换
Custom Type Converters Sometimes, you need to take complete control over the conversion of one type ...
- 【windows核心编程】注入DLL时BUG排除与调试
DLL注入排除bug的思路步骤. 1.在VS中监视输入err,hr检查DLL是否注入成功 2.OD断点loadlibraryW,loadlibraryA是否已经注入成功,eax是否有值. 3.检查路径 ...
- GPIO接口解析【转】
本文提供了一个linux下访问GPIO的约定的概述. 这些调用使用gpio_* 命名前缀.没有别的调用会使用这个前缀或是相关的__gpio_*前缀. 转自:http://blog.163.com/w5 ...
- sqlserver2008 链接服务器 2000
背景 这个项目就有意思了,我用的是sqlserver2008,对方用的是sqlserver2000,还装在windows2000上,是个很老的系统了.两方要对接,对方技术太菜,自己竟然不会转2000. ...
- HTTP基础知识1
HTTP 简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准,它是基于TCP/IP ...
- php单例模式的实例
class Config1 {} class Config { * 必须先声明一个静态私有属性:用来保存当前类的实例 * 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享 * 2. ...
- PHP常见错误提示含义解释
1.Notice: Undefined variable: 变量名 in 注:使用了一个没有被定义的变量 2.Parse error: syntax error, unexpected T_ELSE ...
- 《microsoft sql server 2008技术内幕 t-sql语言基础》
第一章 TSQL编程基础 源代码下载:TSQLFundamentals2008 创建表 USE testdb; CREATE TABLE dbo.Employess ( empid INT NOT N ...
- J 判断二叉树每个结点的权值是否关于根节点完全对称
如果二叉树每个结点的权值关于根节点完全对称 就输出Yes Sample Input 27 //结点1 2 3 //结点1的左孩子是结点2 右孩子是结点32 4 53 6 74 0 05 0 06 0 ...