平衡树学习记录
来源:互联网 发布:淘宝发错货赔偿规则 编辑:程序博客网 时间:2024/06/06 03:16
Treap 普通版 -> set
比较函数简化代码很关键
#include <cstdio>#include <cstdlib>#include <ctype.h>#define Magic 19260817#define ll long long#define max(a,b) a>b?a:b#define min(a,b) a<b?a:btemplate<typename T>inline T read(T &f){ f=0; int x=1; char c=getchar(); while(!isdigit(c)){if(c=='-')x=-1;c=getchar();} while(isdigit(c))f=f*10+c-'0',c=getchar(); return f*x;}struct Node{ Node *ch[2];//左右子树 int r;//节点的优先级 int v;//节点的值 int cmp(int x)const{ if(x==v)return -1; return x<v?0:1; }//比较函数 };void rotate(Node* &node,int staus){ Node *temp=node->ch[staus^1]; node->ch[staus^1]=temp->ch[staus]; temp->ch[staus]=node; node=temp;}//旋转 void insert(Node* &node,int x){ if(node==NULL){ node=new Node(); node->ch[0]=node->ch[1]=NULL; node->v=x; node->r=rand(); } else{ int staus=node->cmp(x); insert(node->ch[staus],x); if((node->ch[staus])->r > node->r) rotate(node,staus^1); }}//插入 void remove(Node* &node,int x){ int staus=node->cmp(x); if(staus==-1){ if(node->ch[0]==NULL)node=node->ch[1]; else if(node->ch[1]==NULL)node=node->ch[0]; else{ int staus1=(node->ch[0] ->r > node->ch[1] ->r)?1:0; rotate(node,staus1); remove(node->ch[staus1],x); } } else remove(node->ch[staus],x);}//删除 int find(Node* node,int x){ while(node!=NULL){ int staus=node->cmp(x); if(staus==-1)return 1; else node=node->ch[staus]; } return 0;}//查询 Node* root;//根节点 void init(){ root=new Node(); root=new Node(); root->ch[0]=root->ch[1]=NULL; root->v=0; root->r=rand();}int n,x;int q,opt;int main(){ srand(Magic);//玄学参数 read(n); for(int i=1;i<=n;i++){ read(x); insert(root,x); } read(q); for(int i=1;i<=q;i++){ read(opt); if(opt==1) printf("%d\n",find(root,read(x))); else remove(root,read(x)); } return 0;}
Treap - ranktree
#include <cstdio>#include <ctype.h>#include <cstdlib>template <typename T>T read(T &f){ f=0; int x=1; char c=getchar(); while(isdigit(c)){if(c=='-')x=-1;c=getchar();} while(!isdigit(c))f=f*10+c-'0',c=getchar(); return f*x;}#define Magic 19260817struct Node{ Node *ch[2];//左右子树 int r;//优先值 int v;//值 int s;//节点个数 Node(int v=0):v(v){ ch[0]=ch[1]=NULL; r=rand(); s=1; }//构造 int cmp(int x)const{ if(x==v) return -1; else return x < v ? 0 : 1; }//比较函数 void maintain(){ s=1; if(ch[0]!=NULL) s+=ch[0]->s; if(ch[1]!=NULL) s+=ch[1]->s; }//更新节点个数 };void rotate(Node* &o,int d){ Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k;}//旋转 void insert(Node* &o,int x){ if(o==NULL) o=new Node(x); else{ int d=(x < o->v ? 0 : 1); insert(o->ch[d],x); if(o->ch[d]->r > o->r) rotate(o,d^1); } o->maintain();}//插入 Node* find(Node* o,int x){ if(o==NULL) return NULL; if(x==o->v) return o; return x < o-> v ? find(o->ch[0],x) : find(o->ch[1],x);}//查找 void remove(Node* &o,int x){ int d=o->cmp(x); int ret=0; if(d==-1){ Node* u=o; if(o->ch[0]!=NULL&&o->ch[1]!=NULL){ int d2=(o->ch[0]->r > o->ch[1]->r ? 1 : 0); rotate(o,d2); remove(o->ch[d2],x); } else{ if(o->ch[0]==NULL) o=o->ch[1]; else o=o->ch[0]; } } else remove(o->ch[d],x); if(o!=NULL) o->maintain();}//移除 int kth(Node* o,int k){ if(o==NULL||k<=0||k>o->s) return 0; int s=(o->ch[0]==NULL ? 0: o->ch[0]->s); if(k==s+1) return o->v; else if(k<=s) return kth(o->ch[0],k); else return kth(o->ch[1],k-s-1);}//求第k小 int rank(Node* o,int x){ if(o==NULL) return 1; if(x<=o->v) return rank(o->ch[0],x); else return rank(o->ch[1],x)+(o->ch[0]==NULL? 0 : o->ch[0]->s)+1;}//求比x小的节点个数 const int INF=1<<28;Node* root= new Node(INF);int m,opt,v;int main(){ scanf("%d",&m); while(m--){ scanf("%d%d",&opt,&v); if(opt==1) insert(root,v); else if(opt==2){ Node *o=find(root,v); printf("%d\n",o == NULL ? 0 : 1); if(o!=NULL) remove(root,v); } else if(opt==3) printf("%d\n",kth(root,v)); else if(opt==4) printf("%d\n",rank(root,v)); } return 0;}
LuoguP3369 【模板】普通平衡树(Treap/SBT)
#include <cstdio>#include <ctype.h>#include <cstdlib>template <typename T>T read(T &f){ f=0; int x=1; char c=getchar(); while(isdigit(c)){if(c=='-')x=-1;c=getchar();} while(!isdigit(c))f=f*10+c-'0',c=getchar(); return f*x;}#define Magic 19260817#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)struct Node{ Node *ch[2];//左右子树 int r;//优先值 int v;//值 int s;//节点个数 Node(int v=0):v(v){ ch[0]=ch[1]=NULL; r=rand(); s=1; }//构造 int cmp(int x)const{ if(x==v) return -1; else return x < v ? 0 : 1; }//比较函数 void maintain(){ s=1; if(ch[0]!=NULL) s+=ch[0]->s; if(ch[1]!=NULL) s+=ch[1]->s; }//更新节点个数 };void rotate(Node* &o,int d){ Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k;}//旋转 void insert(Node* &o,int x){ if(o==NULL) o=new Node(x); else{ int d=(x < o->v ? 0 : 1); insert(o->ch[d],x); if(o->ch[d]->r > o->r) rotate(o,d^1); } o->maintain();}//插入 Node* find(Node* o,int x){ if(o==NULL) return NULL; if(x==o->v) return o; return x < o-> v ? find(o->ch[0],x) : find(o->ch[1],x);}//查找 void remove(Node* &o,int x){ int d=o->cmp(x); int ret=0; if(d==-1){ Node* u=o; if(o->ch[0]!=NULL&&o->ch[1]!=NULL){ int d2=(o->ch[0]->r > o->ch[1]->r ? 1 : 0); rotate(o,d2); remove(o->ch[d2],x); } else{ if(o->ch[0]==NULL) o=o->ch[1]; else o=o->ch[0]; } } else remove(o->ch[d],x); if(o!=NULL) o->maintain();}//移除 int kth(Node* o,int k){ if(o==NULL||k<=0||k>o->s) return 0; int s=(o->ch[0]==NULL ? 0: o->ch[0]->s); if(k==s+1) return o->v; else if(k<=s) return kth(o->ch[0],k); else return kth(o->ch[1],k-s-1);}//求第k小 int rank(Node* o,int x){ if(o==NULL) return 1; if(x<=o->v) return rank(o->ch[0],x); else return rank(o->ch[1],x)+(o->ch[0]==NULL? 0 : o->ch[0]->s)+1;}//求比x小的节点个数 void pre(Node* o,int x,int &ans){ if(o==NULL) return; if(o->v < x){ ans=max(ans,o->v); if(o->ch[1]!=NULL) pre(o->ch[1],x,ans); } else if(o->ch[0]!=NULL) pre(o->ch[0],x,ans);}//求前驱void nxt(Node* o,int x,int &ans){ if(o==NULL) return; if(o->v > x){ ans=min(ans,o->v); if(o->ch[0]!=NULL) nxt(o->ch[0],x,ans); } else if(o->ch[1]!=NULL) nxt(o->ch[1],x,ans);}//求后继 const int INF=1<<28;Node* root= new Node(INF);int m,opt,v;int ans;int main(){ scanf("%d",&m); while(m--){ scanf("%d%d",&opt,&v); if(opt==1) insert(root,v);//插入 else if(opt==2){ Node *o=find(root,v); if(o!=NULL) remove(root,v); }//删除 else if(opt==3) printf("%d\n",rank(root,v));//排名 else if(opt==4) printf("%d\n",kth(root,v));//k大数 else if(opt==5){ ans=0; pre(root,v,ans); printf("%d\n",ans); }//求前驱 else if(opt==6){ ans=INF; nxt(root,v,ans); printf("%d\n",ans); }//求后继 } return 0;}
待补全
阅读全文
0 0
- 平衡树学习记录
- 平衡小车学习记录
- 平衡二叉树(+二叉排列树)(学习记录)
- [平衡树] 平衡树学习笔记
- 平衡树学习小记
- 【学习】Treap平衡树
- 平衡树学习笔记
- 【学习】Splay平衡树
- 平衡树学习导引
- 平衡树学习笔记
- 2017.6.28 文艺平衡树 思考记录
- 学习笔记--(平衡树)splay
- 后缀平衡树学习笔记
- 平衡二叉树学习小节
- 数据结构学习-平衡二叉树
- 数据结构学习笔记-平衡二叉树实现
- 【平衡二叉树】SBT学习笔记
- 平衡树(treap)学习笔记
- linux route命令的使用详解
- POJ 1001 Exponentiation(大树乘法)
- 欢迎使用CSDN-markdown编辑器
- 实例学习AJAX-基础1
- requests库入门-4-HTTP请求方法和用requests举例不带参数的请求
- 平衡树学习记录
- Nmap 渗透实列
- window窗口对象
- Myeclipse错误:Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project
- 【POJ】3045
- OSX上pf的简单配置笔记
- STM8学习笔记三----按键实验
- React 组件解耦之道
- QT 多线程(QThread)里调用线程池(QThreadPool )与主界面进行通讯