BZOJ3065。

去年用pascal 块链过了。。

今年来试了试非旋treap大法   注定被块链完爆

代码留这。

第一份 :辣鸡的  垃圾回收做法  跑得极慢

 #include <bits/stdc++.h>
#define M 70000
using namespace std;
struct W{int l,r,s,v,e;}a[];
struct O{int l,r,s,k;}b[];
int nex[],A[],n,m,rt,ans,l,r,x,k,t,c,T,d[]; char op[];
void CL(int u){
if (!u) return; --b[u].k;
if (!b[u].k) nex[u]=t,t=u;
}
void NEW(int &u){
int U=t; t=nex[t]; CL(u);
CL(b[U].l); CL(b[U].r);
b[U]=(O){b[u].l,b[u].r,b[u].s,};
u=U; ++b[b[u].l].k; ++b[b[u].r].k;
}
void add(int &u,int x,int p,int q,int X){
NEW(u); b[u].s+=X;
if (p<q)
if (x<=p+q>>) add(b[u].l,x,p,p+q>>,X);
else add(b[u].r,x,(p+q>>)+,q,X);
if (!b[u].s) {nex[u]=t; t=u; u=;}
}
void he(int &u,int v,int p,int q){
if (!v) return;
if (!u) {++b[u=v].k; return;}
NEW(u); b[u].s+=b[v].s;
he(b[u].l,b[v].l,p,p+q>>);
he(b[u].r,b[v].r,(p+q>>)+,q);
}
void up(int u){
a[u].s=a[a[u].l].s+a[a[u].r].s+;
CL(a[u].e); a[u].e=;
add(a[u].e,a[u].v,,M,);
he(a[u].e,a[a[u].l].e,,M);
he(a[u].e,a[a[u].r].e,,M);
}
void build(int &u,int p,int q){
if (p>q) return;
u=p+q>>; a[u].v=A[u];
build(a[u].l,p,u-);
build(a[u].r,u+,q);
up(u);
}
void split(int u,int k,int &l,int &r){
if (!k) {l=; r=u; return;}
if (k==a[u].s) {l=u; r=; return;}
if (k<=a[a[u].l].s) split(a[u].l,k,l,a[u].l),up(r=u);
else split(a[u].r,k-a[a[u].l].s-,a[u].r,r),up(l=u);
}
void join(int &u,int k){
if ((1ll+a[u].s)*rand()<=RAND_MAX){
int A,B; split(u,k,A,B);
a[T].l=A; a[T].r=B; up(u=T);
}else{
if (k<=a[a[u].l].s) join(a[u].l,k);
else join(a[u].r,k-a[a[u].l].s-);
add(a[u].e,a[T].v,,M,); ++a[u].s;
}
}
void mody(int u,int k){
if (a[a[u].l].s+==k)
r=a[u].v,a[u].v=l; else
if (k<=a[a[u].l].s) mody(a[u].l,k);
else mody(a[u].r,k-a[a[u].l].s-);
add(a[u].e,r,,M,-);
add(a[u].e,l,,M,);
}
void find(int u,int l,int r){
if (r<||l>a[u].s) return;
if (l<=&&a[u].s<=r) {d[++c]=a[u].e; return;}
if (l<=a[a[u].l].s+&&a[a[u].l].s<r)
add(d[],a[u].v,,M,);
find(a[u].l,l,r);
find(a[u].r,l-a[a[u].l].s-,r-a[a[u].l].s-);
}
int main(){
srand();
scanf("%d",&n);
for (int i=;i<=n;++i) scanf("%d",&A[i]);
for (int i=;i<;++i) nex[i]=i+;
t=; build(rt,,n); T=n;
scanf("%d",&m);
while (m--){
scanf("%s",op);
if (op[]=='Q'){
scanf("%d%d%d",&l,&r,&k);
l^=ans; r^=ans; k^=ans;
c=; find(rt,l,r);
l=; r=M; int tt=d[];
while (l<r){
x=;
for (int i=;i<=c;++i) x+=b[b[d[i]].l].s;
if (x<k){
l=(l+r>>)+; k-=x;
for (int i=;i<=c;++i) d[i]=b[d[i]].r;
}else{
r=l+r>>;
for (int i=;i<=c;++i) d[i]=b[d[i]].l;
}
}
CL(tt); d[]=;
printf("%d\n",ans=l);
}else
if (op[]=='M'){
scanf("%d%d",&k,&l);
l^=ans; k^=ans;
mody(rt,k);
}else{
scanf("%d%d",&l,&k);
l^=ans; k^=ans; --l;
++T; a[T].v=k;
join(rt,l);
}
}
return ;
}

奈奈

第二份:暴力回收,暴力合并,快了许多

 #include <bits/stdc++.h>
#define M 70000
#define S 15000000
using namespace std;
int D[S],rt,t,d[],m,x,l,r,k,n,ans,Q; char OP;
struct O{int l,r,s,v,e;}a[];
struct U{int l,r,s;}b[S];
void cl(int &u){
if (!u) return;
cl(b[u].l); cl(b[u].r);
D[++t]=u; b[u].s=; u=;
}
void add(int &u,int p,int q,int x){
if (!u) u=D[t--]; ++b[u].s;
if (p!=q)
if (x<=p+q>>) add(b[u].l,p,p+q>>,x);
else add(b[u].r,(p+q>>)+,q,x);
}
void del(int &u,int p,int q,int x){
--b[u].s;
if (p!=q)
if (x<=p+q>>) del(b[u].l,p,p+q>>,x);
else del(b[u].r,(p+q>>)+,q,x);
if (!b[u].s) D[++t]=u,u=;
}
int he(int l,int r){
if (!l&&!r) return ;
int u=D[t--];
b[u].s=b[l].s+b[r].s;
b[u].l=he(b[l].l,b[r].l);
b[u].r=he(b[l].r,b[r].r);
return u;
}
void up(int u){
a[u].s=a[a[u].l].s+a[a[u].r].s+;
cl(a[u].e);
a[u].e=he(a[a[u].l].e,a[a[u].r].e);
add(a[u].e,,M,a[u].v);
}
void build(int &u,int p,int q){
if (p>q) return;
u=p+q>>;
build(a[u].l,p,u-);
build(a[u].r,u+,q);
up(u);
}
void find(int u,int l,int r){
if (r<||l>a[u].s) return;
if (l<=&&a[u].s<=r) {d[++m]=a[u].e; return;}
int i=a[a[u].l].s+;
if (l<=i&&i<=r)
add(d[],,M,a[u].v);
find(a[u].l,l,r);
find(a[u].r,l-i,r-i);
}
void mody(int u){
int i=a[a[u].l].s+;
if (i==k) l=a[u].v,a[u].v=r; else
if (k<i) mody(a[u].l);
else k-=i,mody(a[u].r);
del(a[u].e,,M,l);
add(a[u].e,,M,r);
}
void split(int u,int k,int &l,int &r){
if (!k) {l=,r=u; return;}
if (k==a[u].s) {l=u,r=; return;}
if (k<=a[a[u].l].s){
split(a[u].l,k,l,a[u].l); up(r=u);
}else{
split(a[u].r,k-a[a[u].l].s-,a[u].r,r); up(l=u);
}
}
void join(int &u){
if ((1ll+a[u].s)*rand()<=RAND_MAX){
int A,B; split(u,k,A,B);
a[n].l=A; a[n].r=B; up(u=n);
}else{
if (k<=a[a[u].l].s) join(a[u].l);
else k-=a[a[u].l].s+,join(a[u].r);
add(a[u].e,,M,a[n].v); ++a[u].s;
}
}
int main(){
srand();
scanf("%d",&n);
for (int i=;i<=n;++i) scanf("%d",&a[i].v);
for (int i=S-;i;--i) D[i]=++t;
build(rt,,n);
scanf("%d",&Q);
while (Q--){
scanf("\n%c",&OP);
if (OP=='Q'){
scanf("%d%d%d",&l,&r,&k);
l^=ans; r^=ans; k^=ans;
m=; find(rt,l,r);
l=; r=M; int tt=d[];
while (l<r){
x=;
for (int i=;i<=m;++i) x+=b[b[d[i]].l].s;
if (x<k){
l=(l+r>>)+; k-=x;
for (int i=;i<=m;++i) d[i]=b[d[i]].r;
}else{
r=l+r>>;
for (int i=;i<=m;++i) d[i]=b[d[i]].l;
}
}
cl(d[]=tt); printf("%d\n",ans=l);
}else
if (OP=='M'){
scanf("%d%d",&k,&r);
k^=ans; r^=ans;
mody(rt);
}else{
scanf("%d%d",&k,&x);
k^=ans; a[++n].v=x^ans;
--k; join(rt);
}
}
return ;
}

雲珠桜

非旋treap套线段树的更多相关文章

  1. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  2. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  3. BZOJ1901 ZOJ2112 线段树+treap (线段树套线段树)

    BZOJ1901: 线段树套线段树做法: (外层线段树 里层动态开节点的权值线段树) 有一个小小的trick 可以省掉二分变成nlog^2n的 就是把查询的区间都取出来- logn个一起走- 2016 ...

  4. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

  5. 非旋Treap及其可持久化

    平衡树这种东西,我只会splay.splay比较好理解,并且好打,操作方便. 我以前学过SBT,但并不是很理解,所以就忘了怎么打了. 许多用平衡树的问题其实可以用线段树来解决,我们真正打平衡树的时候一 ...

  6. 非旋 treap 结构体数组版(无指针)详解,有图有真相

    非旋  $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ  ...

  7. 2827: 千山鸟飞绝 非旋treap

    国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...

  8. 非旋Treap总结 : 快过Splay 好用过传统Treap

    非旋$Treap$ 其高级名字叫$Fhq\ Treap$,既然叫$Treap$,它一定满足了$Treap$的性质(虽然可能来看这篇的人一定知道$Treap$,但我还是多说几句:$Fhp\ Treap$ ...

  9. 【bzoj4785】[Zjoi2017]树状数组 线段树套线段树

    题目描述 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进行 m 次操作 ...

随机推荐

  1. AngularJS的表单验证提交示例

    代码下载:https://files.cnblogs.com/files/xiandedanteng/angularjsFormSubmit.rar 前台代码: <%@ page content ...

  2. ios 清理缓存(EGO)

    一段清理缓存的代码例如以下: dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,) , ^{ NSSt ...

  3. ffmpeg 错误 real-time buffer [USB2.0 Camera] [video input] too full or near too full (101% of size: 30412)

    利用ffmpeg 获取USB 或者本地摄像机视频,并将视频编码后保存本地文件或者发送到远端流媒体服务经常会出现 类似real-time buffer [USB2.0 Camera] [video in ...

  4. UVA 610 - Street Directions(割边)

    UVA 610 - Street Directions option=com_onlinejudge&Itemid=8&page=show_problem&category=5 ...

  5. javaweb dev 入

    ::::关于jsp页面和servlet之间传递参数 JSP与 servlet之间的传值有两种情况:JSP -> servlet, servlet -> JSP. 通过对象 request和 ...

  6. ARM architecture

    http://en.wikipedia.org/wiki/ARM_architecture ARM architecture     ARM architectures The ARM logo De ...

  7. Python生成器定义

    通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素 ...

  8. ElasticSearch 分页检索

    在ElasticSearch的多索引和多类别里说到我们在集群中有14个文档匹配我们的(空)搜索语句.单数仅仅有10个文档在hits数组中.我们怎样看到其它文档? 和SQL使用LIMITkeyword返 ...

  9. HDU 5384 Danganronpa (2015年多校比赛第8场)

    1.题目描写叙述:点击打开链接 2.解题思路:本题利用字典树解决.本题要求查找全部的B[j]在A[i]中出现的总次数.那么我们能够建立一颗字典树,将全部的B[j]插入字典树,因为一个串的全部字串相当于 ...

  10. 搭建mongoDB 配置副本集 replSet

    mongodb的master_slave和ReplSet是很常见的两种构架: 下面记录下搭建mongodbReplSet 的过程: 首先,进入到一个指定目录下 >cd /opt 下载mongod ...