老管家是一個聰明能幹的人。他爲財主工做了整整10年,財主爲了讓自已帳目更加清楚。要求管家天天記k次帳,因爲管家聰明能幹,於是管家老是讓財主十分滿意。可是因爲一些人的唆使,財主仍是對管家產生了懷疑。因而他決定用一種特別的方法來判斷管家的忠誠,他把每次的帳目按1,2,3…編號,而後不定時的問管家問題,問題是這樣的:在a到b號帳中最少的一筆是多少?爲了讓管家沒時間做假他老是一次問多個問題。ios
輸入中第一行有兩個數m,n表示有m(m<=100000)筆帳,n表示有n個問題,n<=100000。spa
第二行爲m個數,分別是帳目的錢數code
後面n行分別是n個問題,每行有2個數字說明開始結束的帳目編號。get
輸出文件中爲每一個問題的答案。具體查看樣例。io
輸入 #1class
10 3
1 2 3 4 5 6 7 8 9 10
2 7
3 9
1 10stream
輸出 #1方法
2 3 1數據
ST表 + 倍增 + RMQ區間最值查詢
求區間最小值
區間最小值
看到這裏必定會不由自主想到能夠用ST表來作這種區間最值得題目
讀入數據
而後預處理出ST表裏面對應的區間最值是多少
最後輸入須要查詢的區間
而後輸出區間最小值就行了
作這種區間最值題目的時候
必定要考慮好區間的範圍
不要到時候求a到b區間範圍內數最值
由於處理不當致使求到了a到b範圍外面
就會出現很大的問題
#include<iostream> #include<cstdio> using namespace std; int read() { int sum = 0,fg = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-')fg = -1; c = getchar(); } while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); } return sum * fg; } const int Max = 100005; int f[Max][22]; int LG[Max]; int main() { int m = read(),n = read(); for(register int i = 1;i <= m;++ i) f[i][0] = read(); for(register int j = 1;(1 << j) <= m;++ j) for(register int i = 1;i + (1 << j) - 1 <= m;++ i) f[i][j] = min(f[i][j - 1],f[i + (1 << (j - 1))][j - 1]); for(register int i = 1;(1 << i) <= m;++ i) LG[(1 << i)] = i; for(register int i = 1;i <= m;++ i) if(LG[i] == 0) LG[i] = LG[i - 1]; for(register int i = 1;i <= n;++ i) { int a = read(),b = read(); int k = LG[b - a + 1]; cout << min(f[a][k],f[b - (1 << k) + 1][k]) << " "; } return 0; }