[平衡树]BallIntheBox
来源:互联网 发布:天人网络电视在线 编辑:程序博客网 时间:2024/05/21 04:41
题目还是牛耳杯程序设计大赛的D题,之前已经描述过,就不在赘述了。
之前用AVL实现的,这里附上一个用SBT实现的版本,对比发现SBT实现更为简单,而且时空消耗略少。
搓长丑的SBT代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<memory.h>#include<ctime>using namespace std;const int MAXN = 100010;struct KEY{ int wgt; int num; KEY(int w=0,int n=0):wgt(w),num(n){} bool operator == (const KEY &k) const { return wgt==k.wgt&&num==k.num; } bool operator < (const KEY &k) const { if(wgt!=k.wgt)return wgt<k.wgt; return num<k.num; }};struct SBT{ int l[MAXN],r[MAXN],size[MAXN],pool[MAXN],ROOT,TOP,NODE; KEY Key[MAXN]; void init() { TOP = NODE = ROOT = 0; } int newnode(int w,int n) { int node; if(TOP)node = pool[TOP--]; else node = ++NODE; Key[node].wgt = w; Key[node].num = n; size[node] = 1; l[node] = r[node] = 0; return node; } void delnode(int x) { pool[++TOP] = x; Key[x].wgt = Key[x].num = size[x] = l[x] = r[x] = 0; } void left_rotate(int &p) { int x = r[p]; r[p] = l[x]; l[x] = p; size[p] = size[l[p]]+size[r[p]]+1; size[x] = size[l[x]]+size[r[x]]+1; p = x; } void right_rotate(int &p) { int x = l[p]; l[p] = r[x]; r[x] = p; size[p] = size[l[p]]+size[r[p]]+1; size[x] = size[l[x]]+size[r[x]]+1; p = x; } void Maintain(int &p) { if(size[l[l[p]]]>size[r[p]]) { right_rotate(p); Maintain(r[p]); Maintain(p); } if(size[r[l[p]]]>size[r[p]]) { left_rotate(l[p]); right_rotate(p); Maintain(l[p]); Maintain(r[p]); Maintain(p); } if(size[r[r[p]]]>size[l[p]]) { left_rotate(p); Maintain(l[p]); Maintain(p); } if(size[l[r[p]]]>size[l[p]]) { right_rotate(r[p]); left_rotate(p); Maintain(r[p]); Maintain(l[p]); Maintain(p); } } void Maintain_faster(int &p,bool flag) { if(flag==0) { if(size[l[l[p]]]>size[r[p]])right_rotate(p); else if(size[r[l[p]]]>size[r[p]]) { left_rotate(l[p]); right_rotate(p); } else return ; } else { if(size[r[r[p]]]>size[l[p]])left_rotate(p); else if(size[l[r[p]]]>size[l[p]]) { right_rotate(r[p]); left_rotate(p); } else return; } Maintain_faster(l[p],0); Maintain_faster(r[p],1); Maintain_faster(p,1); Maintain_faster(p,0); } void insert(int &p,KEY k) { if(!p) { p = newnode(k.wgt,k.num); return; } if(k<Key[p])insert(l[p],k); else insert(r[p],k); size[p]=size[l[p]]+size[r[p]]+1; Maintain_faster(p,!(k<Key[p])); } int findmin(int p) { if(l[p])return findmin(l[p]); else return p; } void remove(int &p,KEY k) { if(p) { if(k==Key[p]) { if(!l[p]) { int x = p; p = r[p]; delnode(x); } else if(!r[p]) { int x = p; p = l[p]; delnode(x); } else { int x = findmin(r[p]); Key[p] = Key[x]; remove(r[p],Key[x]); } } else if(k<Key[p])remove(l[p],k); else remove(r[p],k); if(p){ size[p] = size[l[p]]+size[r[p]]+1; } //Maintain(p); } } int Select(int p,int k) { int rank = size[l[p]]+1; if(rank==k)return p; else if(rank<k)return Select(r[p],k-rank); return Select(l[p],k); } void print(int p) { if(!p)return; print(l[p]); printf("%d\n",size[p]); print(r[p]); }}sbt;int A[MAXN];int main(){ clock_t start,final; start = clock(); int n,m; freopen("D.in","r",stdin); freopen("Dans.out","w",stdout); while(scanf("%d%d",&n,&m)!=EOF) { sbt.init(); for(int i=1;i<=n;i++)scanf("%d",&A[i]); for(int i=1;i<=n;i++)sbt.insert(sbt.ROOT,KEY(A[i],i)); for(int i=0;i<m;i++) { int x,y;char op[5]; scanf("%s",op); //sbt.print(sbt.ROOT); if(op[0]=='A') { scanf("%d%d",&x,&y); sbt.remove(sbt.ROOT,KEY(A[x],x)); A[x]+=y; sbt.insert(sbt.ROOT,KEY(A[x],x)); } else if(op[0]=='B') { scanf("%d%d",&x,&y); sbt.remove(sbt.ROOT,KEY(A[x],x)); A[x]-=y; sbt.insert(sbt.ROOT,KEY(A[x],x)); } else if(op[0]=='C') { scanf("%d%d",&x,&y); sbt.remove(sbt.ROOT,KEY(A[x],x));sbt.remove(sbt.ROOT,KEY(A[y],y)); A[y]+=A[x]; sbt.insert(sbt.ROOT,KEY(A[y],y)); } else { scanf("%d",&x); printf("%d\n",sbt.Key[sbt.Select(sbt.ROOT,x)].wgt); } } } final = clock(); printf("Time is %lf\n",(double)(final-start)/CLOCKS_PER_SEC); return 0;}
- [平衡树]BallIntheBox
- [平衡树]牛耳杯程序设计大赛决赛D题——BallIntheBox
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 平衡树
- 【平衡树】平衡树教学
- 平衡二叉树平衡法则
- Tyvj P1728 普通平衡树 (平衡树)
- 【bzoj3224】普通平衡树 平衡树
- [平衡树] 平衡树学习笔记
- 平衡树与非平衡树简介
- redis发布订阅和自定义的命令组合
- Learning SQL2
- BASE64编码与解码(Base64Encode,Base64Decode)
- java第二课 java语言基础
- cramfs
- [平衡树]BallIntheBox
- 推荐系统的循序进阶读物(从入门到精通)
- 第6周任务2
- The Dirichlet Distribution 狄利克雷分布 (PRML 2.2.1)
- axis实现webservice 返回对象和数组
- 第六周 任务一
- 从配置文件里读取数据,实现多数据库连接
- FileZilla客户端实现分析
- Your project contains errors, but there is no red cross marks