RMQ——ST算法
来源:互联网 发布:中兴百货知乎 编辑:程序博客网 时间:2024/05/23 20:52
template<typename T>class RMQ{ T **f; int n1; int n2; bool (*cmp)(const T &a,const T &b); bool compare(const T &a,const T &b) { if(cmp==NULL) return a < b; return cmp(a,b); } void init() { for(int i=1;i<=n1;i++) { for(int j=0;j<n2-(1<<i)+1;j++) { f[i][j]=compare(f[i-1][j],f[i-1][j+(1<<(i-1))])?f[i-1][j]:f[i-1][j+(1<<(i-1))]; } } } int log2(int p) { int ans=0; while(p) { ans++; p>>=1; } return ans-1; } public: RMQ():n1(0),n2(0),f(NULL),cmp(NULL){} RMQ(const T *p,const T *q) { n2=q-p; n1=log2(n2); cmp=NULL; f=new T*[n1+1]; for(int i=0;i<=n1;i++) f[i]=new T[n2]; for(int i=0;i<n2;i++) f[0][i]=*(p+i); init(); } RMQ(const T *p,const T *q,bool (*cm)(const T &a,const T &b)) { n2=q-p; n1=log2(n2); cmp=cm; f=new T*[n1+1]; for(int i=0;i<=n1;i++) f[i]=new T[n2]; for(int i=0;i<n2;i++) f[0][i]=*(p+i); init(); } RMQ(int p,T mnt[]):n1(log2(p)),n2(p),cmp(NULL) { f=new T*[n1+1]; for(int i=0;i<=n1;i++) f[i]=new T[n2]; for(int i=0;i<n2;i++) f[0][i]=mnt[i]; init(); } RMQ(int p,T mnt[],bool (*cm)(const T &a,const T &b)):n1(p),n2(log2(p)),cmp(cm) { f=new T*[n1+1]; for(int i=0;i<=n1;i++) f[i]=new T[n2]; for(int i=0;i<n2;i++) f[0][i]=mnt[i]; init(); } RMQ(const RMQ &rm) { *this=rm; } RMQ &operator=(const RMQ &rm) { if(this==&rm) return *this; cmp=rm.cmp; if(f==NULL||n2!=rm.n2) { n1=rm.n1; n2=rm.n2; f=new T*[n1+1]; for(int i=0;i<=n1;i++) f[i]=new T[n2]; } for(int i=0;i<=n1;i++) for(int j=0;j<n2;j++) f[i][j]=rm.f[i][j]; return *this; } ~RMQ() { clear(); } void clear() { if(f==NULL) return ; for(int i=0;i<=n1;i++) delete[] f[i]; delete[] f; } int size(){return n2;} T query(int p,int q) { int len=q-p+1; int l=log2(len); return compare(f[l][p],f[l][q-(1<<l)+1])?f[l][p]:f[l][q-(1<<l)+1]; }};