国际惯例的题面:

这种维护排序序列,严格大于的进行操作的题都很套路......
我们按照[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的更多相关文章

  1. 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 ...

  2. [BZOJ 4923][Lydsy1706月赛]K小值查询

    传送门 势能分析平衡树,splay或treap都可以 放个指针版的就跑 #include <bits/stdc++.h> using namespace std; #define rep( ...

  3. [BZ4923][Lydsy1706月赛]K小值查询

    K小值查询 题面 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. Input ...

  4. BZOJ4923:[Lydsy1706月赛]K小值查询(Splay)

    Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...

  5. BZOJ4923 [Lydsy1706月赛]K小值查询

    题意 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. \(n \leq 10 ...

  6. BZOJ3224普通平衡树——非旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  7. BZOJ3223文艺平衡树——非旋转treap

    此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...

  8. [bzoj3065] 带插入区间第k小值 [重量平衡树套线段树]

    题面 传送门 思路 发现强制在线了...... 本来可以树套树解决的问题,现在外层不能使用线段树了,拿什么替代呢? 我们需要一种支持单点插入.下套数据结构.数据结构上传合并复杂度最多单log,不能旋转 ...

  9. [bzoj4923]K小值查询

    来自FallDream的博客,未经允许,请勿转载,谢谢. 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有 ...

随机推荐

  1. SLAM学习资料汇总

    转自 http://www.cnblogs.com/wenhust/   书籍: 1.必读经典 Thrun S, Burgard W, Fox D. <Probabilistic robotic ...

  2. AutoMapper中用户自定义转换

    Custom Type Converters Sometimes, you need to take complete control over the conversion of one type ...

  3. 【windows核心编程】注入DLL时BUG排除与调试

    DLL注入排除bug的思路步骤. 1.在VS中监视输入err,hr检查DLL是否注入成功 2.OD断点loadlibraryW,loadlibraryA是否已经注入成功,eax是否有值. 3.检查路径 ...

  4. GPIO接口解析【转】

    本文提供了一个linux下访问GPIO的约定的概述. 这些调用使用gpio_* 命名前缀.没有别的调用会使用这个前缀或是相关的__gpio_*前缀. 转自:http://blog.163.com/w5 ...

  5. sqlserver2008 链接服务器 2000

    背景 这个项目就有意思了,我用的是sqlserver2008,对方用的是sqlserver2000,还装在windows2000上,是个很老的系统了.两方要对接,对方技术太菜,自己竟然不会转2000. ...

  6. HTTP基础知识1

    HTTP 简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准,它是基于TCP/IP ...

  7. php单例模式的实例

    class Config1 {} class Config { * 必须先声明一个静态私有属性:用来保存当前类的实例 * 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享 * 2. ...

  8. PHP常见错误提示含义解释

    1.Notice: Undefined variable: 变量名 in 注:使用了一个没有被定义的变量 2.Parse error: syntax error, unexpected T_ELSE ...

  9. 《microsoft sql server 2008技术内幕 t-sql语言基础》

    第一章 TSQL编程基础 源代码下载:TSQLFundamentals2008 创建表 USE testdb; CREATE TABLE dbo.Employess ( empid INT NOT N ...

  10. J 判断二叉树每个结点的权值是否关于根节点完全对称

    如果二叉树每个结点的权值关于根节点完全对称 就输出Yes Sample Input 27 //结点1 2 3 //结点1的左孩子是结点2 右孩子是结点32 4 53 6 74 0 05 0 06 0 ...