RMQ的ST演算法

來源:互聯網
上載者:User

RMQ 即 range maximum/minimum query

  1、樸素(即搜尋),O(n)-O(qn) online。

  2、線段樹,O(n)-O(qlogn) online。

  3、ST(實質是動態規劃),O(nlogn)-O(1) online。

  ST演算法(Sparse Table),以求最大值為例,設d[i,j]表示[i,i+2^j-1]這個區間內的最大值,那麼在詢問到[a,b]區間的最大值時答案就是max(d[a,k], d[b-2^k+1,k]),其中k是滿足2^k<=b-a+1(即長度)的最大的k,即k=[ln(b-a+1)/ln(2)]。

  d的求法可以用動態規劃,d[i,j]=max(d[i,j-1],d[i+2^(j-1),j-1])。

  4、RMQ標準演算法:先規約成LCA(Lowest Common Ancestor),再規約成約束RMQ,O(n)-O(1) online。

 

  首先根據原數列,建立笛卡爾樹,從而將問題線上性時間內規約為LCA問題。LCA問題可以線上性時間內規約為約束RMQ,也就是數列中任意兩個相鄰的數的差都是+1或-1的RMQ問題。約束RMQ有O(n)-O(1)的線上解法,故整個演算法的時間複雜度為O(n)-O(1)。

 

 ST演算法  來看一下ST演算法是怎麼實現的(以最大值為例):

  首先是預先處理,用一個DP解決。設a是要求區間最值的數列,f[i,j]表示從第i個數起連續2^j個數中的最大值。例如數列3 2 4 5 6 8 1 2 9 7 ,f[1,0]表示第1個數起,長度為2^0=1的最大值,其實就是3這個數。f[1,2]=5,f[1,3]=8,f[2,0]=2,f[2,1]=4……從這裡可以看出f[i,0]其實就等於a。這樣,DP的狀態、初值都已經有了,剩下的就是狀態轉移方程。我們把f[i,j](j≥1)平均分成兩段(因為j≥1時,f[i,j]一定是偶數個數字),從i到i+2^(j-1)-1為一段,i+2^(j-1)到i+2^j-1為一段(長度都為2^(j-1))。用上例說明,當i=1,j=3時就是3,2,4,5
和6,8,1,2這兩段。f就是這兩段的最大值中的最大值。於是我們得到了動規方程F[i,j]=max(F[i,j-1],F[i+2^(j-1),j-1])。

  接下來是得出最值,也許你想不到計算出f有什麼用處,一般毛想想計算max還是要O(logn),甚至O(n)。但有一個很好的辦法,做到了O(1)。還是分開來。如在上例中我們要求區間[2,8]的最大值,就要把它分成[2,5]和[5,8]兩個區間,因為這兩個區間的最大值我們可以直接由f[2,2]和f[5,2]得到。擴充到一般情況,就是把區間[l,r]分成兩個長度為2^n的區間(保證有f對應)。直接給出運算式:

  k:=trunc(ln(r-l+1)/ln(2));

  ans:=max(F[l,k],F[r-2^k+1,k]);

  這樣就計算了從l開始,長度為2^k的區間和從r-2^k+1開始長度為2^k的區間的最大值(運算式比較煩瑣,細節問題如加1減1需要仔細考慮),二者中的較大者就是整個區間[l,r]上的最大值。

應用:

JOJ 2660 河床

時間上明顯沒有直接單調隊列維護最大最小快,可能是運算log上浪費了時間。

對log最佳化了下,直接位元運算取ln2稍微快了些

#include <cstdio>#include <cmath>#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)const int maxn=30005;const double ln2=log(2.0);int dpmax[maxn][16],dpmin[maxn][16],w[maxn];int n;int getln2 (int x){    int i;    for(i=0 ; x ; ++i,x>>=1);    return i-1;}void rmqinit (){    for (int i=0 ; i<n ; ++i)    dpmax[i][0]=dpmin[i][0]=w[i];    int m=getln2(n);    for (int i=1 ; i<=m ; ++i)    {        for (int j=n-1 ; j>=0 ; --j)        {            dpmax[j][i]=dpmax[j][i-1];//F[i,j]=max(F[i,j-1],F[i+2^(j-1),j-1])。            if(j+(1<<(i-1))<=n)dpmax[j][i]=max(dpmax[j][i],dpmax[j+(1<<(i-1))][i-1]);            dpmin[j][i]=dpmin[j][i-1];            if(j+(1<<(i-1))<=n)dpmin[j][i]=min(dpmin[j][i],dpmin[j+(1<<(i-1))][i-1]);        }    }}int rmqmin(int l,int r){    int m=getln2(r-l+1);//k:=trunc(ln(r-l+1)/ln(2));    return min(dpmin[l][m],dpmin[r-(1<<m)+1][m]);//ans:=min(F[l,k],F[r-2^k+1,k]);}int rmqmax(int l,int r)//O(1){    int m=getln2(r-l+1);    return max(dpmax[l][m],dpmax[r-(1<<m)+1][m]);}int k;int main (){    while (~scanf("%d%d",&n,&k),(n||k))    {                //printf("%d\n",getln2(6));        for (int i=0 ; i<n ; ++i)        {            scanf("%d",w+i);        }        rmqinit();        int start=0,end=0;        int ans=0;        while(true)        {            int tmpmax=rmqmax(start,end);            int tmpmin=rmqmin(start,end);            //printf("%d  %d  start=%d e=%d\n",tmpmin,tmpmax,start,end);            while(tmpmax-tmpmin<=k && end<n)            {                end++;                tmpmax=rmqmax(start,end);                tmpmin=rmqmin(start,end);            }            //printf("%d  %d  start=%d e=%d\n",tmpmin,tmpmax,start,end);            ans=max(ans,end-start);            tmpmax=rmqmax(start,end);            tmpmin=rmqmin(start,end);            //printf("%d  %d  start=%d e=%d\n",tmpmin,tmpmax,start,end);            while(tmpmax-tmpmin>k && start <=end)            {                start++;                tmpmax=rmqmax(start,end);                tmpmin=rmqmin(start,end);            }            //printf("%d\n",ans);            if(start+ans>n || end>=n )break;        }        printf("%d\n",ans);    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.