BZOJ4923 K小值查询(splay)
容易想到建一棵平衡树,修改时打上标记即可。但是修改会导致平衡树结构被破坏。注意到实际上只有[k+1,2k)这一部分数在平衡树中的位置会被改变,所以对这一部分暴力修改,因为每次都会使其至少减小一半,复杂度非常正确。
开始写的玩意一个点要跑10s吓到我了,卡了半天常(最后也只是在darkbzoj上过了)造了半天bug,调的欲仙欲死,退役了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
#define ll long long
#define N 100010
#define inf 2000000001
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,a[N],root,cnt;
struct data{int x,ch[],fa,s,lazy;
}tree[N<<];
inline void up(int k){tree[k].s=tree[lson].s+tree[rson].s+;}
inline void update(int k,int x){if (k) {if (tree[k].x<inf) tree[k].x-=x;tree[k].lazy+=x;}}
inline void down(int k){if (tree[k].lazy) update(lson,tree[k].lazy),update(rson,tree[k].lazy),tree[k].lazy=;}
inline void push(int k){if (tree[k].fa) push(tree[k].fa);down(k);}
inline int whichson(int k){return tree[tree[k].fa].ch[]==k;}
inline void move(int k)
{
int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
tree[gf].ch[whichson(fa)]=k,tree[k].fa=gf;
tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
tree[k].ch[!p]=fa,tree[fa].fa=k;
up(fa),up(k);
}
void splay(int k,int rt)
{
push(k);
while (tree[k].fa!=rt)
{
int fa=tree[k].fa;
if (tree[fa].fa!=rt)
if (whichson(k)^whichson(fa)) move(k);
else move(fa);
move(k);
}
if (!rt) root=k;
}
void build(int &k,int l,int r)
{
if (l>r) return;
int mid=l+r>>;
k=++cnt;tree[k].x=a[mid],tree[k].s=r-l+;
build(lson,l,mid-);build(rson,mid+,r);
tree[lson].fa=tree[rson].fa=k;
}
int find(int k,int x)
{
if (tree[lson].s+==x) return k;
down(k);
if (tree[lson].s+>x) return find(lson,x);
else return find(rson,x-tree[lson].s-);
}
int qsuf(int k,int x)
{
if (!k) return ;
down(k);
if (tree[k].x<x) return qsuf(rson,x);
else
{
int t=qsuf(lson,x);
return t&&tree[t].x<=tree[k].x?t:k;
}
}
int qpre(int k,int x)
{
if (!k) return ;
down(k);
if (tree[k].x>x) return qpre(lson,x);
else
{
int t=qpre(rson,x);
return t&&tree[t].x>=tree[k].x?t:k;
}
}
void ins(int x)
{
int k=root,fa=;
while (k) down(k),tree[k].s++,fa=k,k=tree[k].x<=x?rson:lson;
k=++cnt;tree[k].x=x,tree[k].s=,tree[k].fa=fa,tree[fa].ch[tree[fa].x<=x]=k;
splay(k,);
}
void dfs(int k,int x)
{
if (!k) return;
down(k);
ins(tree[k].x-x);
dfs(lson,x),dfs(rson,x);
}
void modify(int x)
{
int p=qpre(root,x),q=qsuf(root,*x);
splay(p,);splay(q,p);
int k=tree[q].ch[];tree[q].ch[]=;up(q);up(p);update(q,x);
dfs(k,x);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4923.in","r",stdin);
freopen("bzoj4923.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=;i<=n;i++) a[i]=read();
a[]=,a[n+]=inf;sort(a,a+n+);
build(root,,n+);
for (int i=;i<=m;i++)
{
int op=read(),x=read();
if (op==) printf("%d\n",tree[find(root,x+)].x);
else modify(x);
}
return ;
}
BZOJ4923 K小值查询(splay)的更多相关文章
- BZOJ4923:[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 + 思维
Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...
- [bzoj4923]K小值查询
来自FallDream的博客,未经允许,请勿转载,谢谢. 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有 ...
- [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小值查询
题意 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. \(n \leq 10 ...
- 4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap
国际惯例的题面:这种维护排序序列,严格大于的进行操作的题都很套路......我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好.显然第一个区间的不会变化,第二个区间的会被平移进第一个区 ...
- [BZOJ 4923][Lydsy1706月赛]K小值查询
传送门 势能分析平衡树,splay或treap都可以 放个指针版的就跑 #include <bits/stdc++.h> using namespace std; #define rep( ...
- 【BZOJ】3065: 带插入区间K小值
http://www.lydsy.com/JudgeOnline/problem.php?id=3065 题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175 ...
- 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树
题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...
随机推荐
- 北京Uber优步司机奖励政策(4月14日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 使用Nexus搭建Maven私服问题总结
#业务场景 最近项目要交付给客户了,之前项目开发和测试一直都是使用公司内部的一套环境,项目交付后客户购置了大量服务器,也要将整套测试环境迁移至客户的服务器上,后续的需求变更以及新需求的开发都会在客户服 ...
- tomcat7以上的版本,400BadRequest
出现此原因的解决办法其一,详情可见: https://www.cnblogs.com/dygrkf/p/9088370.html. 另一种解决方法,就是把url中不允许出现的字符编码,后台接收时再解码 ...
- 安装Vue.js的方法有三种
1 使用独立的版本 在Vue.js官网上直接下载,在script标签里引用. 2 使用CND方法(不推荐) 3 NMP 方法 在用Vue.js构建大型应用的时候推荐使用NMP安装方法,NMP能很好的和 ...
- spark重点知识
1 scala 2 spark rdd 3 sprak core 4 性能优化 5 spark sql 6 spark streaming 掌握程度-精通的理解:
- hive的内置函数和自定义函数
一.内置函数 1.一般常用函数 .取整函数 round() 当传入第二个参数则为精度 bround() 银行家舍入法:为5时,前一位为偶则舍,奇则进. .向下取整 floor() .向上取整 ceil ...
- Prometheus+Grafana监控部署实践
参考文档: Prometheus github:https://github.com/prometheus grafana github:https://github.com/grafana/graf ...
- day09,10 函数
一.函数 什么是函数 函数: 对代码块和功能的封装和定义 定义一个事情或者功能. 等到需要的时候直接去用就好了. 那么这里定义的东西就是一个函数. 语法: def 函数名(形参): 函数体 函数名(实 ...
- 关于kv的jch分片存储
确定节点同步一致 节点启动之后,先获取本地的addrbook里面的节点信息 根据获取的addrbook里面的节点信息进行校验(向addrbook里面的节点发送hash消息确认,如果都一样,则可以广播数 ...
- hibernate.hbm.xml文件配置入门小结(1)
在Hibernate中,各表的映射文件xxx.hbm.xml可以通过工具生成,例如在使用MyEclipse开发时,它提供了自动生成映射文件的工具. hibernate.hbm.xml文件的基本结构如下 ...