[學習筆記]RMQ學習筆記

問題:
給定一個序列w,給出若干查詢,輸出區間[l,r]中的最大值或最小值。

原理:
RMQ主要以dp爲基礎實現的。首先預處理,用f[i][j]表示從i後2^j長度的序列的最大值(或最小值),則f[i][2^0]=w[i],類似線段樹,將區間[i,j]分成兩等份(由於j,表示的是2^j的區間長度,所以f[i][j]所表示的區間個數一定爲偶數),那麼狀態轉移方程爲:f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1])//2^(j-1)表示分成兩份後一份的長度.
對於查詢,這裏也把區間分成兩份。令k=log2(r-l+1),則答案就爲ans=max(f[l][k],f[r-2^k+1][k])。
時間複雜度:預處理O(nlogn),查詢O(1)。

代碼:
for(int j=1; j<=m; ++j)
  for(int i=1; i<=m; ++i)
    if(i+(1<<j)-1<=m)
      f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
	    
for(int i=1; i<=n; ++i)
{
	scanf("%d%d",&x,&y);
	int k=log(y-x+1)/log(2);
	printf("%d ",min(f[x][k],f[y-(1<<k)+1][k]));
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章