无旋Treap
Posted 探险家Mr.H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无旋Treap相关的知识,希望对你有一定的参考价值。
听说NOI系列考试不能用平板电视
所以手写了一个无旋Treap 有可能之后进化成fhq Treap
谁知道呢
bzoj3224
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cstdlib> #include<cmath> #define P pair<int,int> using namespace std; inline int ran() { static int seed=19260817; seed+=(seed<<2)+1; return seed; } int op,n,x; struct Treap { struct Treapnode { int ls,rs,val,size; int rnd; }tr[100010]; int rt,sz; inline void update(int id){tr[id].size=tr[tr[id].ls].size+tr[tr[id].rs].size+1;} inline int merge(int a,int b) { if(a==0 || b==0)return a+b; if(tr[a].rnd<tr[b].rnd)return tr[a].rs=merge(tr[a].rs,b),update(a),a; else return tr[b].ls=merge(a,tr[b].ls),update(b),b; } inline P split(int a,int n) { if(n==0)return make_pair(0,a); int L=tr[a].ls,R=tr[a].rs; if(n==tr[L].size)return tr[a].ls=0,update(a),make_pair(L,a); if(n==tr[L].size+1) return tr[a].rs=0,update(a),make_pair(a,R); if(n<tr[L].size) { P tmp=split(L,n); return tr[a].ls=tmp.second,update(a),make_pair(tmp.first,a); } P tmp=split(R,n-tr[L].size-1); return tr[a].rs=tmp.first,update(a),make_pair(a,tmp.second); } inline int rank(int x,int rt) { int ans=0,tmp=2147483233; while(rt) { if(x==tr[rt].val)tmp=min(tmp,ans+tr[tr[rt].ls].size+1); if(x>tr[rt].val)ans+=tr[tr[rt].ls].size+1,rt=tr[rt].rs; else rt=tr[rt].ls; } return tmp==2147483233?ans:tmp; } inline int find(int x,int id) { while(1) { if(tr[tr[id].ls].size==x-1)return tr[id].val; if(tr[tr[id].ls].size>x-1)id=tr[id].ls; else x=x-tr[tr[id].ls].size-1,id=tr[id].rs; } } inline int pre(int x,int k) { int ans=-(int)1e9; while(k) { if(tr[k].val<x)ans=max(ans,tr[k].val),k=tr[k].rs; else k=tr[k].ls; } return ans; } inline int suf(int x,int k) { int ans=(int)1e9; while(k) { if(tr[k].val>x)ans=min(ans,tr[k].val),k=tr[k].ls; else k=tr[k].rs; } return ans; } inline void add(int x) { int k=rank(x,rt); P tmp=split(rt,k); tr[++sz].val=x; tr[sz].rnd=ran(); tr[sz].size++; rt=merge(tmp.first,sz); rt=merge(rt,tmp.second); } inline void del(int x) { int k=rank(x,rt); P t1=split(rt,k); P t2=split(t1.first,k-1); rt=merge(t2.first,t1.second); } }treap; int main() { treap.rt=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&op,&x); if(op==1)treap.add(x); else if(op==2)treap.del(x); else if(op==3)printf("%d\n",treap.rank(x,treap.rt)); else if(op==4)printf("%d\n",treap.find(x,treap.rt)); else if(op==5)printf("%d\n",treap.pre(x,treap.rt)); else printf("%d\n",treap.suf(x,treap.rt)); } return 0; }
以上是关于无旋Treap的主要内容,如果未能解决你的问题,请参考以下文章