2018/2/17 每日一學 RMQ
阿新 • • 發佈:2018-02-19
pre 區間dp 什麽是 極值 ++ 想想 i++ i+1 bsp
什麽是RMQ?
給予n個數,對於區間[l,r]查詢最小、最大值。
這就是RMQ。
怎麽做?
我們不妨設f[i][j]表示從i開始的2^j個數極值。
顯然,他表示的是[i,i+2^j-1],註意有-1(想想,為什麽?)
那麽我們不難得到遞推式:f[i][j]=min/max(f[i][j-1]+f[i+1<<(j-1)+1][j-1]。
註意先枚舉j,聯系以下區間dp不難明白為什麽先枚舉j。
最後怎麽查詢???
很簡單,分治的思想。
假設我們查詢[x,y],則ans=max/min([x][k],[y-1<<k+1][k].
這個k怎麽求,由題意得:x+2^k>=y-2^k+1.
得,y-x+1<=2^(k+1)
所以就很簡單了,k=log2(y-x+1)
看代碼吧:
void ST(int n) { for (int i = 1; i <= n; i++) dp[i][0] = A[i]; for (int j = 1; (1 << j) <= n; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } } } int RMQ(int l, int r) { int k = 0; while ((1 << (k + 1)) <= r - l + 1) k++; return min(dp[l][k], dp[r - (1 << k) + 1][k]); }
2018/2/17 每日一學 RMQ