Treap
可持久化,多種區間操作
merge操作
int merge(int a, int b)
{
if(!a || !b) return a+b
if(rnd(b)>=rnd(a)){
l(b)=merge(a,l(b))
} else {
r(a)=merge(r(a),b)
}
}
split操作
pii split(int o, int val)
{
if(!o) return pii(0,0);
if(val>=val(o)){
pii tmp=split(r(o),val);
r(o)=tmp.first; update(o);
return pii(o, tmp.second);
} else {
pii tmp=split(l(o),val);
l(o)=tmp.second; update(o);
return pii(tmp.first, o);
}
}
模板題
[Tyvj 1728]普通平衡數
完整模板
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define File(x) "phs."#x
#define For(i,s,e) for(int i=(s); i<=(e); i++)
#define Rep(i,s,e) for(int i=(s); i>=(e); i--)
using namespace std;
const int N=30*1e5+10,inf=0x7fffffff;
typedef pair<int,int> pii;
struct TREAP{
int l,r,val,size,rnd;
#define l(x) T[x].l
#define r(x) T[x].r
#define val(x) T[x].val
#define s(x) T[x].size
#define rnd(x) T[x].rnd
}T[N];
int root,len,ans,n;
int addPoint(int val)
{
len++; val(len)=val; s(len)=1; r(len)=l(len)=0; rnd(len)=rand(); return len;
}
void update(int o){ s(o)=s(l(o))+s(r(o))+1; }
int merge(int a, int b)
{
if(!a || !b) return a+b;
if(rnd(b)>=rnd(a)){
l(b)=merge(a,l(b)); update(b); return b;
} else {
r(a)=merge(r(a),b); update(a); return a;
}
}
pii split(int o, int val)
{
if(!o) return pii(0,0);
if(val>=val(o)){
pii tmp=split(r(o),val);
r(o)=tmp.first; update(o);
return pii(o, tmp.second);
} else {
pii tmp=split(l(o),val);
l(o)=tmp.second; update(o);
return pii(tmp.first, o);
}
}
void insert(int val)
{
pii tmp=split(root,val);
root=merge(merge(tmp.first, addPoint(val)), tmp.second);
}
int del(int o, int val)
{
if(!o) return 0;
if(val==val(o)) return merge(l(o), r(o));
if(val>val(o)){
r(o)=del(r(o),val); update(o);
} else {
l(o)=del(l(o),val); update(o);
}
return o;
}
int find(int val)
{
pii tmp=split(root, val-1); int ret=s(tmp.first)+1; root=merge(tmp.first,tmp.second);
return ret;
}
int findx(int o, int x)
{
if(!o) return 0;
if(s(l(o))+1==x) return val(o);
if(s(l(o))>=x) return findx(l(o),x);
return findx(r(o), x-s(l(o))-1);
}
void pre(int val, int o)
{
if(!o) return;
if(val(o)<val) ans=val(o),pre(val,r(o));
else pre(val,l(o));
}
void next(int val, int o)
{
if(!o) return;
if(val(o)>val) ans=val(o),next(val,l(o));
else next(val, r(o));
}
int main()
{
freopen(File(in),"r",stdin);
freopen(File(out),"w",stdout);
cin>>n;
while(n--)
{
int opt,x; scanf("%d %d",&opt,&x);
switch(opt)
{
case 1: insert(x); break;
case 2: root=del(root,x); break;
case 3: printf("%d\n",find(x)); break;
case 4: printf("%d\n",findx(root,x)); break;
case 5: pre(x, root); printf("%d\n",ans); break;
case 6: next(x, root); printf("%d\n",ans); break;
}
}
return 0;
}