Dynamic Query System 基本SBT
2011-04-13 23:24
253 查看
SBT神器啊,川大校赛出了个基本的SBT,他们搞的数据有点恶心,写了好几次都没过掉
http://222.196.33.254/oj/showproblem?problem_id=1716
这个是我们学院上的地址,不过好像只有教育网可以登
感觉SBT就是size一个信息就可以解决n多动态查询问题了
这个可以用来当做模板,自己写的代码可读性还是比较高
http://222.196.33.254/oj/showproblem?problem_id=1716
这个是我们学院上的地址,不过好像只有教育网可以登
感觉SBT就是size一个信息就可以解决n多动态查询问题了
这个可以用来当做模板,自己写的代码可读性还是比较高
/* * File: main.cpp * Author: Mi * * Created on 2011年4月13日, 下午7:51 */ #include <cstdlib> #include <stdio.h> #include <string.h> #include <algorithm> #include <cassert> #define N 500005 using namespace std; /* * */ int tol=0; struct SBT { int left,right; int key; int size; void init() { left=right=0; size=1; } }T ; void R_Rotate(int &t)//右旋 { int k=T[t].left; T[t].left=T[k].right; T[k].right=t; T[k].size=T[t].size; T[t].size=T[T[t].left].size+T[T[t].right].size+1; t=k; return ; } void L_Rotate(int &t)//左旋 { int k=T[t].right; T[t].right=T[k].left; T[k].left=t; T[k].size=T[t].size; T[t].size=T[T[t].left].size+T[T[t].right].size+1; t=k; } void Maintain(int &t,bool flag)//维护,SBT精华之所在 { if(flag==false) { if(T[T[T[t].left].left].size>T[T[t].right].size) R_Rotate(t); else if(T[T[T[t].left].right].size>T[T[t].right].size) { L_Rotate(T[t].left); R_Rotate(t); } else return ; } else { if(T[T[T[t].right].right].size>T[T[t].left].size) L_Rotate(t); else if(T[T[T[t].right].left].size>T[T[t].left].size) { R_Rotate(T[t].right); L_Rotate(t); } else return ; } Maintain(T[t].left,false); Maintain(T[t].right,true); Maintain(t,false); Maintain(t,true); } void Insert(int &t,int v)//插入 { if(t==0) { t=++tol; T[t].init(); T[t].key=v; } else { T[t].size++; if(v<T[t].key) Insert(T[t].left,v); else Insert(T[t].right,v); Maintain(t,v>=T[t].key); } } int Delete(int &t,int v)//删除 { if(!t) return 0; T[t].size--; if(v==T[t].key||v<T[t].key&&!T[t].left||v>T[t].key&&!T[t].right) { if(T[t].left&&T[t].right) { int p=Delete(T[t].left,v+1); T[t].key=T[p].key; return p; } else { int p=t; t=T[t].left+T[t].right; return p; } } else return Delete(v<T[t].key?T[t].left:T[t].right,v); } int Find_k(int t,int k)//找出第k大数 { if(k<=T[T[t].left].size) return Find_k(T[t].left,k); else if(k>T[T[t].left].size+1) return Find_k(T[t].right,k-T[T[t].left].size-1); return T[t].key; } int Getmin(int t)//取最小值 { while(T[t].left) t=T[t].left; return t; } int Getmax(int t)//取最大值 { while(T[t].right) t=T[t].right; return t; } int Rank(int t,int key)//排名其实就是它的左子树的size+1 { if(t==0) return 0; if(key<=T[t].key) return Rank(T[t].left,key); else return T[T[t].left].size+1+Rank(T[t].right,key); } int Exist(int t,int x)//判断这个节点是否存在 { if(t==0) return 0; if(x<T[t].key) return Exist(T[t].left,x); else if(x==T[t].key) return 1; else return Exist(T[t].right,x); } int Count(int t,int x)//统计出现次数 { if(!Exist(t,x)) return 0; else return Rank(t,x+1)-Rank(t,x); } int Pred(int t,int v)//返回比v小的最大的数 { if(t==0) return v; else if(v>T[t].key) { int ret=Pred(T[t].right,v); if(ret==v) return T[t].key; return ret; } else return Pred(T[t].left,v); } int Succ(int t,int v)//返回比v大的最小的数 { if(t==0) return v; else if(v<T[t].key) { int ret=Succ(T[t].left,v); if(ret==v) return T[t].key; return ret; } else return Succ(T[t].right,v); } int main(int argc, char** argv) { int t,q; // freopen("j1.in","r",stdin); // freopen("out.out","w",stdout); scanf("%d",&t); while(t--) { int root=0; tol=0; scanf("%d",&q); while(q--) { char str[5]; int x; scanf("%s",str); if(str[0]=='I') { scanf("%d",&x); Insert(root,x); } else if(str[0]=='R') { scanf("%d",&x); if(Exist(root,x)) Delete(root,x); } else if(str[0]=='S') printf("%d/n",T[root].size); else if(str[0]=='L') { scanf("%d",&x); printf("%d/n",Rank(root,x)); } else if(str[0]=='W') { scanf("%d",&x); if(x<1||x>T[root].size) printf("-1/n"); else printf("%d/n",Find_k(root,x)); } else if(str[0]=='C') { scanf("%d",&x); printf("%d/n",Count(root,x)); } else if(str[1]=='I') { if(root==0) puts("-1"); else printf("%d/n",T[Getmin(root)].key); } else if(str[1]=='A') { if(root==0) puts("-1"); else printf("%d/n",T[Getmax(root)].key); } /* else if(str[0]=='P') { scanf("%d",&x); printf("%d/n",Pred(root,x)); } else if(str[1]=='U') { scanf("%d",&x); printf("%d/n",Succ(root,x)); }*/ } } return 0; }
相关文章推荐
- UESTC 395 Dynamic Query System --Treap
- UESTC395 Dynamic Query System 【简单平衡树(数组Treap)】
- 【转】借助System.Linq.Dynamic, IQueryable根据排序字符串排序
- 传入字典的模型项的类型为“System.Data.Entity.DynamicProxies.
- Mybatis Dynamic Query 前言
- 利用System.IO中的Directory类对目录进行基本操作
- asp.net mvc 2 Could not load type 'System.Web.Mvc.ViewPage<dynamic>'错误解决办法
- MySQL Query 的优化—Query 语句优化基本思路和原则
- 无法将类型“System.Data.Entity.Infrastructure.DbQuery<TZM.TROA.Model.RoleInfo>”转换为“System.Collections.Gene
- System.Data.OleDb.OleDbException: Operation must use an updateable query
- 已以用户 NT AUTHORITY\SYSTEM 的身份执行。 Error formatting query, probably invalid parameters [SQLSTATE 42000]
- 传入字典的模型项的类型为“System.Data.Entity.Infrastructure.DbQuery`1[MapScience.PovertyAlleviation.Web.Models.Qu
- "$err" : "not authorized for query on admin.system.namespaces"
- CentOS6.6系统中system-config-kickstart的基本用法
- Unable to load type System.Data.Entity.DynamicProxiesXXXXXrequired for deserialization.
- 传入字典的模型项的类型为“System.Data.Entity.DynamicProxies.
- 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
- Mybatis Dynamic Query 2.0.2
- 黑马程序员--常用API(String、基本数据类型的包装类、System、Runtime、Date、Calendar、Math)
- Hdu 3686 Traffic Real Time Query System(双联通分量+LCA)