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];    }};