Treap小结
来源:互联网 发布:java怎么写入csv文件 编辑:程序博客网 时间:2024/05/18 11:50
Treap(Tree+Heap)---是一种通过 rand() 来随机生成数字作为修正值来调整的平衡树。
基本操作:
1.旋转。
2.插入(合并重复的),删除(懒惰删除)。
3.查最值,求第k小,求排名。
4.中序遍历就是从小到大的。
5.维护附加关键字.
1.求第k小:
POJ1442
//123211991442Accepted976K204MSC++2080B2013-11-22 20:33:35静态//123212161442Accepted1804K329MSC++2125B2013-11-22 20:39:40动态#include <iostream>#include<cstdio>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;#define MAX 30005int a[MAX];int u[MAX];int tot;class Node{public: int vol,fix; int size; Node *left; Node *right; int lsize(){return left?left->size:0;} int rsize(){return right?right->size:0;}}*root;//space[MAX]void left_rotate(Node *&a){ Node *b=a->right; a->right=b->left; b->left=a; a=b; b=a->left; b->size=b->lsize()+b->rsize()+1; a->size=a->lsize()+a->rsize()+1;}void right_rotate(Node *&a){ Node *b=a->left; a->left=b->right; b->right=a; a=b; b=a->right; b->size=b->lsize()+b->rsize()+1; a->size=a->lsize()+a->rsize()+1;}void insert(Node*&p,int vol){ if(!p) { p=new Node(); //p=&space[tot++]; //静态 p->fix=rand(); p->vol=vol; p->size=1; } else if(vol<=p->vol) { insert(p->left,vol); p->size++; if(p->left->fix < p->fix) right_rotate(p); } else { insert(p->right,vol); p->size++; if(p->right->fix < p->fix) left_rotate(p); }}int get_kth(Node *&p,int k){ int key=p->lsize()+1; if(k < key) return get_kth(p->left,k); else if(k > key) return get_kth(p->right,k-key); else return p->vol;}void init(){ root=NULL; //memset(space,0,sizeof(space));静态 //tot=1;}int main(){ srand(time(0)); int n,m; while(~scanf("%d%d",&m,&n)) { for(int i=1;i<=m;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&u[i]); int j=1; init(); for(int i=1;i<=m;i++) { insert(root,a[i]); while(j<=n&&i==u[j]) { printf("%d\n",get_kth(root,j)); j++; } if(j>n) break; } } return 0;}
2.动态求最值
//123217283481Accepted212K282MSC++1857B2013-11-22 22:26:19动态#include <iostream>#include<cstdlib>#include<ctime>#include<cstdio>#include<cstring>using namespace std;//#define MAX 10000005class Node{public: int vol,fix,cus; Node* left; Node* right;}*root;//,space[MAX] int tot=1;void r_rotate(Node*&a){ Node*b=a->left; a->left=b->right; b->right=a; a=b; b=a->right;}void l_rotate(Node*&a){ Node*b=a->right; a->right=b->left; b->left=a; a=b; b=a->left;}void insert(Node*&p,int cus,int vol){ if(!p) { p=new Node(); //p=&space[tot++]; p->fix=rand(); p->vol=vol; p->cus=cus; } else if(p->vol >= vol) { insert(p->left,cus,vol); if(p->left->fix < p->fix) r_rotate(p); } else { insert(p->right,cus,vol); if(p->right->fix < p->fix) l_rotate(p); }}int Min(Node*&p){ if(!p)return 0; if(!p->left) { Node*t=p; int ans=p->cus; p=p->right; delete t; return ans; } else return Min(p->left);}int Max(Node*&p){ if(!p)return 0; if(!p->right) { Node*t=p; int ans=p->cus; p=p->left; delete t; return ans; } else return Max(p->right);}int main(){ srand(time(0)); int a; while(~scanf("%d",&a)&&a) { if(a==1) { int b,c; scanf("%d%d",&b,&c); insert(root,b,c); } else if(a==3) { printf("%d\n",Min(root)); } else { printf("%d\n",Max(root)); } } return 0;}
3.区间第k小:
//123298082761Accepted3500K1844MSC++3889B2013-11-25 21:28:45静态//123298362761Accepted3900K3922MSC++3962B2013-11-25 21:34:10动态#include <iostream>#include<cstdio>#include<ctime>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;#define MAX 2000005int dog[MAX];int ans[MAX];class Interval{public: int s,e,k; int id; bool operator<(const Interval a) const { return s<a.s; }}qu[MAX];class Node{public: int vol,fix,size; Node*left; Node*right; int lsize(){return left?left->size:0;} int rsize(){return right?right->size:0;}}*root,space[MAX];int tot;void r_rotate(Node*&a){ Node*b=a->left; a->left=b->right; b->right=a; a=b; b=a->right; b->size=b->lsize()+b->rsize()+1;/**RE在这里,不要把求size顺序搞反了*/ a->size=a->lsize()+a->rsize()+1;}void l_rotate(Node*&a){ Node*b=a->right; a->right=b->left; b->left=a; a=b; b=a->left; b->size=b->lsize()+b->rsize()+1; a->size=a->lsize()+a->rsize()+1;}void insert(Node*&p,int vol){ if(!p) { p=&space[tot++]; //p=new Node(); p->left=NULL; p->right=NULL; p->fix=rand(); p->vol=vol; p->size=1; } else if(p->vol > vol) { p->size++; insert(p->left,vol); if(p->left->fix < p->fix) r_rotate(p); } else { p->size++; insert(p->right,vol); if(p->right->fix < p->fix) l_rotate(p); }}void del(Node*&p,int key){ if(!p) return ; p->size--; /**注意size的减减**/ if(key==p->vol) { if(!p->left || !p->right) { //Node *t=p; if(!p->left) p=p->right; else p=p->left; //delete t; } else { if(p->right->fix < p->left->fix) { l_rotate(p); p->size--;/**注意size的减减**/ del(p->left,key); } else { r_rotate(p); p->size--;/**注意size的减减**/ del(p->right,key); } } } else if(key < p->vol) del(p->left,key); else del(p->right,key);}int find_kth(Node*&p,int k){ int sum=p->lsize()+1; if(k < sum) { return find_kth(p->left,k); } else if(k>sum) { return find_kth(p->right,k-sum); } else { return p->vol; }}int solve(Interval t1,Interval t2){ for(int i=t1.s;i<=min(t2.s-1,t1.e);i++) del(root,dog[i]); if(t1.e > t2.e) { for(int i=t2.e+1;i<=t1.e;i++) del(root,dog[i]); } for(int i=max(t1.e+1,t2.s);i<=t2.e;i++) insert(root,dog[i]); return find_kth(root,t2.k);}int main(){ srand(time(0)); //int T; //scanf("%d",&T); int n,m; while(~scanf("%d%d",&n,&m)) { root=NULL; tot=1; memset(space,NULL,sizeof(space)); for(int i=1;i<=n;i++) scanf("%d",&dog[i]); for(int i=1;i<=m;i++) { scanf("%d%d%d",&qu[i].s,&qu[i].e,&qu[i].k); if(qu[i].s > qu[i].e) swap(qu[i].s,qu[i].e); qu[i].id=i; } sort(qu+1,qu+1+m); for(int i=qu[1].s;i<=qu[1].e;i++) insert(root,dog[i]); ans[qu[1].id]=find_kth(root,qu[1].k); for(int i=2;i<=m;i++) { ans[qu[i].id]=solve(qu[i-1],qu[i]); } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}
- Treap小结
- Treap树学习小结
- [模板]treap小结
- treap学习小结(一)
- Treap和Splay学习小结
- 可持久化Treap学习小结
- Treap
- Treap
- Treap
- Treap
- Treap
- Treap
- treap
- Treap
- treap
- Treap
- treap
- Treap
- tomcat 三种模式
- Dijkstra 算法介绍以及实现
- activemq 用jmx监控activemq的配置步骤
- C# 用户权限管理
- StarWind iSCSI Target5.4图文教程
- Treap小结
- 取消Windows Server 2008管理员密码&设置自动登录
- 时下的XX币会不会成为AMD的救命稻草?
- 动态生成Table
- tomcat部署web应用的三种方式
- 二进制的高精度计算
- 位运算
- 邮件服务器
- 36.C++模板