难以想象..
2016-06-11 22:52
411 查看
替罪羊树只插入远远慢于std::set...
我比较了sgt的4种实现..
(much slower)
(略有修改)
(much slower)
我比较了sgt的4种实现..
Set.zball
/// public domain #include <set> using namespace std; set<int> p; int main(){ for(int i=1;i<=1000000;++i) p.insert(i); return 0; }
no opt: 0.64s
-O2: 0.24s
ScapegoatTree.zball
/// 这份代码妥妥的public domain. #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> typedef double fl; typedef unsigned long long ull; const fl alpha = 0.75; const fl ialpha = 1./alpha; const int maxn = 1001000; const ull ullMax = 9223372036854775807; namespace AlphaProcessor{ /// Process alpha usable routines int HeightMin[200]; inline void InitMins(double p=0.){ for(int i=1;(p=pow(ialpha,i))<=maxn*ialpha*ialpha*ialpha;++i) HeightMin[i]=int(p); } } using namespace AlphaProcessor; namespace ScapegoatTree{ #define fsiz(x) (x?x->siz:0) struct sgtNode{ int val,siz; // ull id,idl,idr; sgtNode*l,*r,*f; inline sgtNode*pu(){ siz=fsiz(l)+fsiz(r)+1; return this; } }; struct sgt{ sgtNode tr[maxn],*trp,*root,*trr[maxn]; sgt():trp(tr){} sgtNode* get(int val/*,ull idl,ull idr*/,sgtNode*fa){ sgtNode*ret=trp++; // ull iid=(idl+idr)>>1; *ret=(sgtNode){ val, 1, // iid , idl , idr, NULL, NULL, fa }; return ret; } sgtNode*build(sgtNode*fa,int l,int r/*,ull idl,ull idr*/){ if(l>r) return NULL; int mid=(l+r)>>1,pval=trr[mid]->val; // ull iid=(idl+idr)>>1; if(l==r){ *trr[mid]=(sgtNode){ pval, 1, // iid , idl , idr, NULL, NULL, fa }; return trr[mid]; }else{ *trr[mid]=(sgtNode){ pval, 0, // iid , idl , idr, build(trr[mid],l,mid-1/*,idl,iid-1*/), build(trr[mid],mid+1,r/*,iid+1,idr*/), fa }; return trr[mid]->pu(); } } int flatten(sgtNode*flattenNode,int trrIndex=1){ if(!flattenNode) return trrIndex; trrIndex=flatten(flattenNode->l,trrIndex); trr[trrIndex++]=flattenNode; trrIndex=flatten(flattenNode->r,trrIndex); return trrIndex; } sgtNode*rebuild(sgtNode*rootRebuild){ // ull idl=rootRebuild->idl, idr=rootRebuild->idr; int flattenLen=flatten(rootRebuild)-1; return build(NULL,1,flattenLen/*,idl,idr*/); } sgtNode*insert(int val,int dep=1){ sgtNode*proot=root, *pfat=NULL; while(proot){ ++proot->siz, ++dep; pfat=proot; if(val<=proot->val) proot=proot->l; else proot=proot->r; } sgtNode*ret=NULL; if(pfat){ if(val<=pfat->val) ret=(pfat->l=get(val/*,pfat->idl,pfat->id-1*/,pfat)); else ret=(pfat->r=get(val/*,pfat->id+1,pfat->idr*/,pfat)); }else root=ret=get(val/*,0,ullMax*/,NULL); if(HeightMin[dep]>root->siz){ sgtNode*rr=ret->f; while(rr){ int p=int(((rr->siz)*alpha)); if((fsiz(rr->l)>p)||(fsiz(rr->r)>p)){ sgtNode*p=rr->f; sgtNode*res=rebuild(rr); if(p){ res->f=p; if(p->l==rr) p->l=res; else p->r=res; }else root=res; break; } rr=rr->f; } } return ret; } } vsgt; } using namespace ScapegoatTree; sgtNode* vk[maxn]; int main(){ AlphaProcessor::InitMins(); for(int i=1;i<=1000000;++i){ vk[i]=vsgt.insert(i); } return 0; }
no opt: 0.75s
-O2: 0.4s
alpha=0.805: 0.643s
alpha=0.805 -O2: 0.321s
ScapegoatTree.OIRed2015
/// py交易来的代码.. /// 版权归OIRed2015所有, 转载请询问其本人. QQ: 305626341 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<bitset> #include<set> #include<map> #include<cmath> #include<vector> #include<queue> #include<ctime> #include<cassert> using namespace std; typedef double db; typedef long double ld; typedef unsigned long long ull; typedef long long ll; typedef unsigned int uint; #define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define rep2(i,a,b) for(int (i)=(a);(i)<(b);(i)++) #define per(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define Rep(p,x) for(int (p)=head[(x)];(p);(p)=nxt[(p)]) #define Rep2(p,x) for(int (p)=cur[(x)];(p);(p)=nxt[(p)]) #define ms(x,y) memset(x,y,sizeof x) #define w1 first #define w2 second #define mp make_pair #define pa pair<int,int> #define pb push_back #define ins insert #define lowbit(x) ((x)&(-x)) #define sqr(x) ((x)*(x)) #define SZ(x) (int((x).size())) #define cle(x) ((x).clear()) template<class T>inline void rread(T&num){ num=0;T f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar(); num*=f; } inline int getgcd(int x,int y){if(!x)return y;return getgcd(y%x,x);} inline ll getlcm(int x,int y){return (ll)x/getgcd(x,y)*y;} inline ll getgcd(ll x,ll y){if(!x)return y;return getgcd(y%x,x);} inline ll getlcm(ll x,ll y){return x/getgcd(x,y)*y;} inline int power(int x,int k,int p){int res=1;for(;k;k>>=1,x=(ll)x*x%p)if(k&1)res=(ll)res*x%p;return res;} inline ll power(ll x,ll k,ll p){ll res=1;for(;k;k>>=1,x=x*x%p)if(k&1)res=res*x%p;return res;} const double pi=acos(-1); inline void judge(){ freopen("input.txt","r",stdin); } //********************************head************************************* const int maxn=1000005; int arc[maxn]; typedef int node; namespace Sgt{ const db alpha=0.75; int nowx,root,ndtot,top; int sz[maxn],ls[maxn],rs[maxn]; int st[maxn]; int key[maxn]; inline void dfs(int x){ if(!x)return; dfs(ls[x]); st[++top]=x; dfs(rs[x]); } inline int build(int L,int R){ if(L>R)return 0; int Mid=(L+R)>>1,now=st[Mid]; sz[now]=R-L+1; ls[now]=build(L,Mid-1); rs[now]=build(Mid+1,R); return now; } inline void rebuild(int &x){ top=0;dfs(x); x=build(1,top); nowx=0; } inline void update(int x){ sz[x]=sz[ls[x]]+sz[rs[x]]+1; } inline int insert(int &x,node num){ if(!x){ x=++ndtot; key[x]=num; sz[x]=1; return x; } if(num==key[x])return x; int res; if(num<key[x]){ res=insert(ls[x],num); if(sz[ls[x]]<sz[x]*alpha){ if(nowx)rebuild(ls[x]); }else nowx=x; }else{ res=insert(rs[x],num); if(sz[rs[x]]<sz[x]*alpha){ if(nowx)rebuild(rs[x]); }else nowx=x; } update(x); return res; } #undef mid }using namespace Sgt; int n,m; int main(){ for(int i=1;i<=1000000;++i){ insert(root,i); if(nowx) rebuild(root); } return 0; }
no opt: 0.933s
-O2: 0.466s
ScapegoatTree.Kuangbin
/// 听说是Kuangbin的模板. 修改自http://blog.csdn.net/u010660276/article/details/44162183 ,如果博主认为造成了不好的影响请联系我. #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; const int maxn=1000010; const double alpha=0.75; int N; struct Node { Node *ch[2]; int size,key,nodeCount; bool exist; bool isBad() { return ch[0]->nodeCount>alpha*nodeCount+5||ch[1]->nodeCount>alpha*nodeCount+5; } void pushup() { size=exist+ch[0]->size+ch[1]->size; nodeCount=1+ch[0]->nodeCount+ch[1]->nodeCount; } }; struct ScapeGoatTree { Node pool[maxn]; Node *tail,*root,*null; Node *bc[maxn]; int bc_top; void init() { tail=pool; null=tail++; null->ch[0]=null->ch[1]=null; null->size=null->key=null->nodeCount=0; root=null; bc_top=0; } Node *newNode(int key) { Node *p; if(bc_top)p=bc[--bc_top]; else p=tail++; p->ch[0]=p->ch[1]=null; p->size=1; p->key=key; p->nodeCount=1; p->exist=true; return p; } void Travel(Node *p,vector<Node *>&v) { if(p==null)return; Travel(p->ch[0],v); if(p->exist)v.push_back(p); else bc[bc_top++]=p; Travel(p->ch[1],v); } Node *divide(vector<Node *>&v,int l,int r) { if(l>=r)return null; int mid=(l+r)>>1; Node *p=v[mid]; p->ch[0]=divide(v,l,mid); p->ch[1]=divide(v,mid+1,r); p->pushup(); return p; } void rebuild(Node *&p) { vector<Node *>v; Travel(p,v); p=divide(v,0,v.size()); } Node **insert(Node *&p,int val) { if(p==null) { p=newNode(val); return &null; } else { p->size++; p->nodeCount++; int d=(val>=p->key); Node **res=insert(p->ch[d],val); if(p->isBad())res=&p; return res; } } void insert(int val) { Node **p=insert(root,val); if(*p!=null)rebuild(*p); } void erase(Node *p,int id) { if(p->exist&&id==p->ch[0]->size+1) { p->exist=0; p->size--; return; } p->size--; if(id<=p->ch[0]->size+p->exist) erase(p->ch[0],id); else erase(p->ch[1],id-p->ch[0]->size-p->exist); } int rank(int val) { Node *now=root; int ans=1; while(now!=null) { if(now->key>=val)now=now->ch[0]; else { ans+=now->ch[0]->size+now->exist; now=now->ch[1]; } } return ans; } int get_kth(int k) { Node *now=root; while(now!=null) { if(now->exist&&k==now->ch[0]->size+1) return now->key; else if(now->ch[0]->size>=k)now=now->ch[0]; else { k-=now->ch[0]->size+now->exist; now=now->ch[1]; } } } void erase(int val) { erase(root,rank(val)); if(root->size<alpha*root->nodeCount) rebuild(root); } }tree; int main() { int op,x; tree.init(); for(int i=1;i<=1000000;++i) tree.insert(i); return 0; }
(much slower)
ScapegoatTree.Li Zhuohan(不知道谁,博主如果认为侵犯了您的权益请留言,我会删除代码)
from: http://www.cnblogs.com/zhuohan123/p/3562539.html(略有修改)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const double a=0.75; inline int getnum() { int ans=0,fh=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fh*=-1;ch=getchar();} while(ch>='0'&&ch<='9')ans=ans*10+ch-'0',ch=getchar(); return fh*ans; } struct node{int s[2],f,size,num;}t[2100000];int tnum,root; inline void init() { tnum=2;root=1; t[1].num=-2147483647;t[1].size=2;t[1].s[1]=2; t[2].num=2147483647;t[2].size=1;t[2].f=1; } inline bool balance(int po) { return (double)t[po].size*a>=(double)t[t[po].s[0]].size &&(double)t[po].size*a>=(double)t[t[po].s[1]].size; } int E[1100000],esize; void travel(int po) { if(t[po].s[0])travel(t[po].s[0]); E[++esize]=po; if(t[po].s[1])travel(t[po].s[1]); } int build(int l,int r) { if(l>r)return 0; int mid=(l+r)/2,po=E[mid]; t[t[po].s[0]=build(l,mid-1)].f=po; t[t[po].s[1]=build(mid+1,r)].f=po; t[po].size=t[t[po].s[0]].size+t[t[po].s[1]].size+1; return po; } inline void rebuild(int po) { esize=0;travel(po); int fa=t[po].f,ws=(t[t[po].f].s[1]==po); int npo=build(1,esize); t[t[fa].s[ws]=npo].f=fa; if(po==root)root=npo; } inline void insert(int num) { int now=root,npo=++tnum; t[npo].size=1;t[npo].num=num; while(true) { t[now].size++; bool ws=(num>=t[now].num); if(t[now].s[ws])now=t[now].s[ws]; else {t[t[now].s[ws]=npo].f=now;break ;} } int inv=0; for(int i=npo;i;i=t[i].f)if(!balance(i))inv=i; if(inv)rebuild(inv); } inline int rank(int num) { int now=root,ans=0; while(now) { if(t[now].num<num)ans+=t[t[now].s[0]].size+1,now=t[now].s[1]; else now=t[now].s[0]; } return ans; } inline int getkth(int kth) { int now=root; while(true) { if(t[t[now].s[0]].size==kth-1)return now; else if(t[t[now].s[0]].size>=kth)now=t[now].s[0]; else kth-=t[t[now].s[0]].size+1,now=t[now].s[1]; } return now; } inline int getn(int num) { int now=root; while(true) { if(t[now].num==num)return now; else now=t[now].s[t[now].num<num]; } } inline void erase(int po) { if(t[po].s[0]&&t[po].s[1]) { int tpo=t[po].s[0]; while(t[tpo].s[1])tpo=t[tpo].s[1]; t[po].num=t[tpo].num; po=tpo; } int son=(t[po].s[0])?t[po].s[0]:t[po].s[1],ws=(t[t[po].f].s[1]==po); t[t[t[po].f].s[ws]=son].f=t[po].f; for(int i=t[po].f;i;i=t[i].f)t[i].size--; if(po==root)root=son; } inline int succ(int num) { int now=root,ans=2147483647; while(now) { if(t[now].num>num)ans=min(ans,t[now].num),now=t[now].s[0]; else now=t[now].s[1]; } return ans; } inline int pred(int num) { int now=root,ans=-2147483647; while(now) { if(t[now].num<num)ans=max(ans,t[now].num),now=t[now].s[1]; else now=t[now].s[0]; } return ans; } int main(int argc, char *argv[]) { init(); for(int i=1;i<=1000000;++i) insert(i); return 0; }
(much slower)
相关文章推荐
- centos7.2 虚拟机多网卡处理
- 算法-蓝桥杯习题(4-2)
- leetcode_c++: Maximum Product Subarray(152)
- 【CSS笔记八】CSS代码缩写,占用更少的带宽
- Android 闹钟设置详解
- 第四百三十五天 how can i 坚持
- JS--浏览器兼容之new Date
- awk命令
- C#实现对邮件的发送
- Mysql Master-slave 主从配置
- Photoshop CS6 MAC 中文版破解版 支持Retina屏
- Linux下的函数调用原理—栈帧
- C++ Virtual详解
- linux awk命令详解
- Android四大组件--Broadcast Receiver
- 勿忘初心
- Count and Say
- c++动态绑定
- 山东省第七届ACM竞赛 J题 Execution of Paladin (题意啊)
- 关于Goroutine的原理