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\)小值.他 ...
随机推荐
- Android Sdk Manager更新
现在Android Sdk Manager无法更新了,什么原因大家都知道,即使使用Goagent效果也不理想. 目前Goagent使用的3.2.2 修改C:\Windows\System32\driv ...
- 【转载】C/C++杂记:NULL与0的区别、nullptr的来历
原文:C/C++杂记:NULL与0的区别.nullptr的来历 某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. ...
- replace与replaceAll的区别
这两者有些人很容易搞混,因此我在这里详细讲述下. replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了 ...
- python 的入门
时光匆匆,大一的时间过的很快,从大一上学期学的c开始,就感觉出c的结构很复杂,但是不可否认,学习c和汇编等涉及到系统底层知识才会有可能开发出属于自己知识产权的东西,然而,python以其简约性,丰富的 ...
- HDU-6315:Naive Operations(线段树+思维)
链接:HDU-6315:Naive Operations 题意: In a galaxy far, far away, there are two integer sequence a and b o ...
- Valgrind 简单用法
有时需要给自己写的小程序做个简单的 benchmark,查看内存使用情况和运行时间.这时可以试试 valgrind. Ubuntu 下安装很简单: sudo apt-get update sudo a ...
- Codeforces Round #765 Div.1 F. Souvenirs 线段树
题目链接:http://codeforces.com/contest/765/problem/F 题意概述: 给出一个序列,若干组询问,问给出下标区间中两数作差的最小绝对值. 分析: 这个题揭示着数据 ...
- 7. I/O复用
一.I/O复用的特点 能同时监听多个文件描述符 自身是阻塞的 当多个文件描述符同时就绪时,如果不采取额外的措施,程序就只能按顺序依次处理其中的每一个文件描述符 由于其第三个特点,所以服务器程序看起来仍 ...
- TensorFlow:NameError: name ‘input_data’ is not defined
在运行TensorFlow的MNIST实例时,第一步 import tensorflow.examples.tutorials.mnist.input_data mnist = input_data. ...
- 图论---POJ 3660 floyd 算法(模板题)
是一道floyd变形的题目.题目让确定有几个人的位置是确定的,如果一个点有x个点能到达此点,从该点出发能到达y个点,若x+y=n-1,则该点的位置是确定的.用floyd算发出每两个点之间的距离,最后统 ...