1068 : RMQ-ST算法
阿新 • • 發佈:2018-07-31
隨機數 turn 0ms 區間 意義 hihocode coder 宇宙 div
#1068 : RMQ-ST算法
時間限制:10000ms 單點時限:1000ms 內存限制:256MB描述
小Hi和小Ho在美國旅行了相當長的一段時間之後,終於準備要回國啦!而在回國之前,他們準備去超市采購一些當地特產——比如漢堡(大霧)之類的回國。
但等到了超市之後,小Hi和小Ho發現者超市擁有的商品種類實在太多了——他們實在看不過來了!於是小Hi決定向小Ho委派一個任務:假設整個貨架上從左到右拜訪了N種商品,並且依次標號為1到N,每次小Hi都給出一段區間[L, R],小Ho要做的是選出標號在這個區間內的所有商品重量最輕的一種,並且告訴小Hi這個商品的重量,於是他們就可以毫不費勁的買上一大堆東西了——多麽可悲的選擇困難癥患者。
(雖然說每次給出的區間仍然要小Hi來進行決定——但是小Hi最終機智的選擇了使用隨機數生成這些區間!但是為什麽小Hi不直接使用隨機數生成購物清單呢?——問那麽多做什麽!)
提示一:二分法是宇宙至強之法!(真的麽?)
提示二:線段樹不也是二分法麽?
輸入
每個測試點(輸入文件)有且僅有一組測試數據。
每組測試數據的第1行為一個整數N,意義如前文所述。
每組測試數據的第2行為N個整數,分別描述每種商品的重量,其中第i個整數表示標號為i的商品的重量weight_i。
每組測試數據的第3行為一個整數Q,表示小Hi總共詢問的次數。
每組測試數據的第N+4~N+Q+3行,每行分別描述一個詢問,其中第N+i+3行為兩個整數Li, Ri,表示小Hi詢問的一個區間[Li, Ri]。
對於100%的數據,滿足N<=10^6,Q<=10^6, 1<=Li<=Ri<=N,0<weight_i<=10^4。
輸出
對於每組測試數據,對於每個小Hi的詢問,按照在輸入中出現的順序,各輸出一行,表示查詢的結果:標號在區間[Li, Ri]中的所有商品中重量最輕的商品的重量。
- 樣例輸入
-
10 7334 1556 8286 1640 2699 4807 8068 981 4120 2179 5 3 4 2 8 2 4 6 8 7 10
- 樣例輸出
-
1640 981 1556 981 981
方法一:線段樹1 #include <iostream> 2
方法二:RMQ,st1 #include <iostream> 2 #include <cmath> 3 #define N 1000005 4 using namespace std; 5 int an[N]; 6 int dp[N][40]; 7 int t,n; 8 9 void st(int n){ 10 for(int i = 1;i <= n;++i) 11 dp[i][0] = an[i]; 12 for(int i = 1;(1<<i) <= n; ++i){ 13 for(int j = 1; j+(1<<i)-1 <= n; ++j){ 14 dp[j][i] = min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); 15 } 16 } 17 } 18 int rmq(int l,int r){ 19 int k = 0; 20 while((1<<(k+1)) <= (r-l+1)) 21 k++; 22 return min(dp[l][k],dp[r-(1<<k)+1][k]); 23 } 24 int main(){ 25 scanf("%d",&t); 26 for(int i=1;i<=t;i++){ 27 scanf("%d",&an[i]); 28 } 29 st(t); 30 scanf("%d",&n); 31 for(int i=1;i<=n;i++){ 32 int x,y; 33 scanf("%d%d",&x,&y); 34 printf("%d\n", rmq(x,y)); 35 } 36 return 0; 37 }
1068 : RMQ-ST算法