题目链接

文艺平衡树的可持久化版,可以使用treap实现。

作为序列使用的treap相对splay的优点如下:

1.代码短

2.容易实现可持久化

3.边界处理方便(splay常常需要在左右两端加上保护结点以防越界,而treap一般不用)

可以分裂合并的treap一般称作无旋treap或FHQ-treap,不过我个人觉得它的结构和普通的treap没什么两样,只是多了个分裂和合并的操作而已...

代码:

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e7+,inf=0x3f3f3f3f;
int ch[N][],val[N],siz[N],rd[N],rev[N],tot,n,m,rt[N];
ll sum[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
int newnode(int x) {int u=++tot; val[u]=sum[u]=x,siz[u]=,rd[u]=rand(),l(u)=r(u)=rev[u]=; return u;}
int cpy(int u) {int w=++tot; val[w]=val[u],sum[w]=sum[u],rd[w]=rd[u],siz[w]=siz[u],rev[w]=rev[u],l(w)=l(u),r(w)=r(u); return w;}
void pu(int u) {siz[u]=siz[l(u)]+siz[r(u)]+,sum[u]=sum[l(u)]+sum[r(u)]+val[u];}
void pd(int u) {
if(rev[u]) {
rev[u]=;
if(l(u))l(u)=cpy(l(u));
if(r(u))r(u)=cpy(r(u));
swap(l(u),r(u));
rev[l(u)]^=,rev[r(u)]^=;
}
}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
pd(w);
if(k>=siz[l(w)]+)u=cpy(w),sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=cpy(w),sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v) {
if(!u||!v) {w=u|v; return;}
if(rd[u]>rd[v])pd(u),w=u,mg(r(w),r(u),v);
else pd(v),w=v,mg(l(w),u,l(v));
pu(w);
}
void rv(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
rev[M]^=;
mg(u,L,M),mg(u,u,R);
}
void ins(int& u,int p,int x) {
int L,M,R;
sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R);
}
void del(int& u,int p) {
int L,M,R;
sp(u,p,L,R),sp(L,p-,L,M),mg(u,L,R);
}
ll qry(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=sum[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
int main() {
srand(time());
scanf("%d",&n);
ll last=;
for(int i=; i<=n; ++i) {
int a,b,c,d;
scanf("%d%d%d",&a,&b,&c),c^=last;
if(b!=)scanf("%d",&d),d^=last;
rt[i]=rt[a];
if(b==)ins(rt[i],c,d);
else if(b==)del(rt[i],c);
else if(b==)rv(rt[i],c,d);
else printf("%lld\n",last=qry(rt[i],c,d));
}
return ;
}

还有一种实现方法是去掉每个结点的随机因子,在合并的时候改用rand函数来决定哪个结点作为哪个节点的父亲,判断rand()%(siz[u]+siz[v])和siz[u]的大小关系就行了。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e7+,inf=0x3f3f3f3f;
int ch[N][],val[N],siz[N],rev[N],tot,n,m,rt[N];
ll sum[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
int newnode(int x) {int u=++tot; val[u]=sum[u]=x,siz[u]=,l(u)=r(u)=rev[u]=; return u;}
int cpy(int u) {int w=++tot; val[w]=val[u],sum[w]=sum[u],siz[w]=siz[u],rev[w]=rev[u],l(w)=l(u),r(w)=r(u); return w;}
void pu(int u) {siz[u]=siz[l(u)]+siz[r(u)]+,sum[u]=sum[l(u)]+sum[r(u)]+val[u];}
void pd(int u) {
if(rev[u]) {
rev[u]=;
if(l(u))l(u)=cpy(l(u));
if(r(u))r(u)=cpy(r(u));
swap(l(u),r(u));
rev[l(u)]^=,rev[r(u)]^=;
}
}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
pd(w);
if(k>=siz[l(w)]+)u=cpy(w),sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=cpy(w),sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v) {
if(!u||!v) {w=u|v; return;}
if(rand()%(siz[u]+siz[v])<siz[u])pd(u),w=u,mg(r(w),r(u),v);
else pd(v),w=v,mg(l(w),u,l(v));
pu(w);
}
void rv(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
rev[M]^=;
mg(u,L,M),mg(u,u,R);
}
void ins(int& u,int p,int x) {
int L,M,R;
sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R);
}
void del(int& u,int p) {
int L,M,R;
sp(u,p,L,R),sp(L,p-,L,M),mg(u,L,R);
}
ll qry(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=sum[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
int main() {
srand(time());
scanf("%d",&n);
ll last=;
for(int i=; i<=n; ++i) {
int a,b,c,d;
scanf("%d%d%d",&a,&b,&c),c^=last;
if(b!=)scanf("%d",&d),d^=last;
rt[i]=rt[a];
if(b==)ins(rt[i],c,d);
else if(b==)del(rt[i],c);
else if(b==)rv(rt[i],c,d);
else printf("%lld\n",last=qry(rt[i],c,d));
}
return ;
}

最新文章

  1. PHP的两种表单数据提交方式
  2. myeclipse激活时cracker2015.jar打不开
  3. GZFramework代码生成器插件使用教程
  4. 在线教学、视频会议 Webus Fox(2) 服务端开发手册
  5. [复变函数]第17堂课 5 解析函数的 Laurent 展式与孤立奇点 5. 1 解析函数的 Laurent 展式
  6. 20145305《Java程序设计》实验三
  7. jquery-easyui使用
  8. Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二)
  9. android-Activity的执行流程
  10. 【玩转Ubuntu】08. Linux报错:Syntax error: &quot;(&quot; unexpected解决办法
  11. 图片组件——axure线框图部件库介绍
  12. scrapy学习总结
  13. 让数字变化炫酷起来,数字滚动Text组件[Unity]
  14. 休眠(1):sleep和wait的区别
  15. 【shiro】(5)---基于Shiro的权限管理
  16. ABP框架系列之九:(Abp-Session-会话)
  17. 如何使用Visual Studio 2017调试.net库源代码
  18. 转载-vim配置收藏
  19. 防止 IE 自动跳兼容模式
  20. python文件读写模式 --- r,w,a,r+,w+,a+,rb,wb

热门文章

  1. Java学习笔记之ArrayList基本用法
  2. 实现Servlet接口
  3. 关于add migration 报错的问题解决方案
  4. vue2.X + HTML5 plus 拍照和调用设备相册 另附 图片转base64和压缩图片方法
  5. Node.js使用redis进行订阅发布管理
  6. [转帖]56核Xeon Platinum 9200现身 - 英特尔有史以来最大的CPU封装
  7. Windown Server 2008配置tomcat9虚拟路径
  8. 洛谷 P3857 彩灯 题解
  9. SPOJ 4003 Phone List 题解
  10. 遍历dataframe