文章目录
RMQ问题
不带修改的区间最值,重叠的区间不会对区间的最大值产生影响
可以用 ST表(稀疏表)
(不带修改的区间问题可以用,一经修改就不可以用了)
例题模板:区间最值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| int dp[8][35];
int query(int l, int r ) { int j = (int)log2(r - l + 1); return max(dp[l][j], dp[r - (1 << j) + 1][j]); }
int main() { int arr[8] = { 9,3,1,7,5,6,0,8 }; int n = 8;
for (int i = 0; i < n; i++) { dp[i][0] = arr[i]; }
for (int j = 1; j <= log2(n); j++) { for (int i = 0; i + (1 << j) - 1 < n; i++) { dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
} int l, r; while (cin >> l >> r) { cout << query(l, r) << endl; } return 0; }
|
例题:区间最大公约数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| int gcd(int a,int b) { return b?gcd(b,a%b):0; }
int dp[8][35];
int query(int l, int r) { int j = (int)log2(r - l + 1); return gcd(dp[l][j], dp[r - (1 << j) + 1][j]); }
int main() { int arr[8] = { 9,3,15,12,5,6,0,8 }; int n = 8; for (int i = 0; i < n; i++) { dp[i][0] = arr[i]; }
for (int j = 1; j <= log2(n); j++) { for (int i = 0; i + (1 << j) - 1 < n; i++) { dp[i][j] = gcd(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
} int l, r; while (cin >> l >> r) { cout << query(l, r) << endl; } return 0; }
|
区间最大间距
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include<iiostream> using namespace std; int dpmax[30][35]; int dpmin[30][35];
int querymax(int l, int r) { int j =(int) log2(r - l + 1); return max(dpmax[l][j], dpmax[r - (1 >> j) + 1][j] ); }
int querymin(int l, int r) { int j = (int)log2(r - l + 1); return min(dpmin[l][j], dpmin[r - (1 << j) + 1][j]); }
int main() { int n,m; cin >> n>>m; int arr[25]; for(int i = 0; i < n; i++) { cin >> arr[i]; dpmax[i][0] = arr[i]; dpmin[i][0] = arr[i]; } for (int j = 1; j <= log2(n); j++) { for (int i = 0; i + (1 << j) - 1 < n; i++) { dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); dpmin[i][j]=min(dpmin[i][j - 1], dpmin[i + (1 << (j - 1))][j-1]);
} } while (m--) { int l, r; cin >> l >> r; cout << querymax(l,r)-querymin(l,r) << endl; } return 0; }
|