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,将所有 ...
随机推荐
- 升级版updateOozie.sh
以前的版本检测当天的Tar包,并只能选择1个Tar包进行更新代码,当天生成多个版本时需修改脚本中配置,并不方便. 升级版兼容目录下存在一个或者多个Tar包的情况: 1.单个Tar包时,直接解压缩到当前 ...
- AT91RM9200---定时器简介
1.前言 系统定时器模块集成了3个不同的定时器 一个周期性间隔的定时器,用来为操作系统设置时基 一个看门狗定时器,可用于软件死锁时进行系统复位 一个实时时钟计数器用来记录流逝的时间 系统定时器时钟 这 ...
- [转]AMBA、AHB、APB、ASB总线简介
[转]http://www.cnblogs.com/zhaozhong1989/articles/3092140.html 1.前言 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大.数字IC ...
- 利用capability特征加强Linux系统安全【转】
转自:https://blog.csdn.net/fivedragon/article/details/676849 1.简介 UNIX是一种安全操作系统,它给普通用户尽可能低的权限,而把全部的系统权 ...
- 基于 OpenSSL 的 CA 建立及证书签发
http://rhythm-zju.blog.163.com/blog/static/310042008015115718637/ 建立 CA 建立 CA 目录结构 按照 OpenSSL 的默认配置建 ...
- 反向代理负载均衡之APACHE
反向代理负载均衡之APACHE 一.反向代理1.1 介绍反响代理 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将 ...
- 使用Navicat Premium对mssql2008r2授权用户
使用Navicat Premium操作mssql2008r2数据库 比如需要对某个特定的数据tes添加一个管理员em,并且这个管理员只能对test这个数据库进行操作 使用sa连接数据库 1.新建一个登 ...
- Android用户界面开发:Fragment
Android用户界面开发:Fragment 1:注意事项 3.0以前的Android 版本要使用FragmentActivity 来装载Fragment ,使用到support v4包. 3.0 ...
- mockito简单教程
注:本文来源:sdyy321的<mockito简单教程> 官网: http://mockito.org API文档:http://docs.mockito.googlecode.com/h ...
- CCF2015122消除类游戏(C语言版)
问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消 ...