您的位置:首页 > 其它

【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树

2017-07-12 11:56 513 查看
直接上代码 正所谓 人傻自带大常数

平衡树的几种姿势: AVL Red&Black_Tree 码量爆炸,不常用;SBT 出于各种原因,不常用。

常用:

Treap 旋转 基于旋转操作和随机数堆 但不支持区间操作。

非旋转 基于随机数堆和拆分合并操作 常数较大

时间复杂度:很难被卡,均摊O(logN)

#include <cstdio>
using namespace std;
const int A=24,fix=10000000;
inline void read (int &now){
register char word=getchar();bool temp=false;
for(now=0;word<'0'||word>'9';word=getchar())if(word=='-')temp=true;
for(;word>='0'&&word<='9';now=(now<<1)+(now<<3)+word-'0',word=getchar());
if(temp)now=-now;
}
struct Trie{
Trie *ch[2];int size;
void* operator new(size_t);
}*root,*null,*C,*mempool;
void* Trie :: operator new(size_t){
if(C==mempool)C=new Trie[(1<<21)+10],mempool=C+(1<<21)+10;
return C++;
}
inline Trie *New(){
register Trie *p=new Trie;
p->ch[0]=p->ch[1]=null,p->size=0;
return p;
}
int n;
inline void Insert(int x,int size){
register Trie *p=root;x+=fix;
for(int i=A;i>=0;i--){
if(p->ch[(x>>i)&1]==null)p->ch[(x>>i)&1]=New();
p=p->ch[(x>>i)&1];p->size+=size;
}
}
inline int get_Rank(int x){
register int ret=0;x+=fix;register Trie *p=root;
for(register int i=A;i>=0&&p!=null;i--)
if(x&(1<<i))ret+=p->ch[0]->size,p=p->ch[1];
else p=p->ch[0];
return ret;
}
inline int get_Kth(int k){
register Trie *p=root;register int ret=0;
for(register int i=A;i>=0;i--)
if(p->ch[0]->size>=k)p=p->ch[0];
else ret|=(1<<i),k-=p->ch[0]->size,p=p->ch[1];
return ret-fix;
}
int main(){
freopen("phs.in","r",stdin);freopen("phs.out","w",stdout);
null=new Trie,null->ch[0]=null->ch[1]=null,null->size=0,root=new Trie,root->ch[0]=root->ch[1]=null,root->size=0;
read(n);register int opt,x;
while(n--){
read(opt),read(x);
switch(opt){
case 1:Insert(x,1);break;
case 2:Insert(x,-1);break;
case 3:printf("%d\n",get_Rank(x)+1);break;
case 4:printf("%d\n",get_Kth(x));break;
case 5:printf("%d\n",get_Kth(get_Rank(x)));break;
case 6:printf("%d\n",get_Kth(get_Rank(x+1)+1));break;
}
}
}


01Trie
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: