题意很简单就是给你两个数n和m,n表示有n张飞机票,m表示有m次查询,接下来n行,每行两个数,分别表示航班出发的时间和价格,接下来m行,每行两个数表示查询这两个数时间内航班最贵的价格。如果没有要求的机票就输出"None"。这道题是一道典型的RMQ问题,就是区间最值查询问题。这里提供两种解法。
1.线段树可以解决,而且是一道线段树的裸题。
//segment tree #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 100005; int result; struct tree { int left; int right; int value; }tree[N*4]; void build(int l, int r, int p) { tree[p].left = l; tree[p].right = r; int mid = (l+r)/2; if(l == r) { tree[p].value = 0; return ; } build(l, mid, p*2); build(mid+1, r, p*2+1); tree[p].value = max(tree[p*2].value, tree[p*2+1].value); } void update(int t, int value, int p) { int mid = (tree[p].left + tree[p].right) / 2; if(tree[p].left == tree[p].right) { tree[p].value = max(tree[p].value, value); return ; } if(t<=mid) update(t, value, p*2); else update(t, value, p*2+1); tree[p].value = max(tree[p*2].value, tree[p*2+1].value); } void query(int l, int r, int p) { int mid = (tree[p].left + tree[p].right) / 2; if(tree[p].left == l && tree[p].right == r) { result = max(result, tree[p].value); return ; } if(r <= mid) query(l, r, p*2); else if(l > mid) query(l, r, p*2+1); else { query(l, mid, p*2); query(mid+1, r, p*2+1); } } int main() { int n, m; scanf("%d%d", &n, &m); build(1, n, 1); for(int i=0; i<n; i++) { int t, v; scanf("%d%d", &t, &v); update(t, v, 1); } for(int i=0; i<m; i++) { int l, r; result = 0; scanf("%d%d", &l, &r); query(l, r, 1); if(result == 0) cout<<"None"<<endl; else cout<<result<<endl; } return 0; }2.用ST算法也可以解决。
算法分析:预处理时间复杂度为O(n*log(n)),但是查询的复杂度是O(1),预处理就是用一个二维数组data[a][b]表示从a到2^b内数的最值,然后用一个DP来更新所有的值,最后查询输出结果。
//RMQ解决区间最值问题 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; const int N = 100005; int input[N]; int price[N][40]; void rmq(int num) { int tmp = int(log(num*1.0) / log(2.0)); for(int i=1; i<=num; i++) price[i][0] = input[i]; for(int j=1; j<=tmp; j++) for(int i=1; i<=num; i++) { if(i+(1<<j) <= num) price[i][j] = max(price[i][j-1], price[i+(1<<(j-1))][j-1]); } } int main() { int n, m; scanf("%d%d", &n, &m); memset(input, 0, sizeof(input)); for(int i=0; i<n; i++) { int pos, pri; scanf("%d%d", &pos, &pri); input[pos] = max(pri, input[pos]); } rmq(N-1); for(int i=0; i<m ;i++) { int result, l, r; scanf("%d%d", &l, &r); int tmp = log((r-l+1)*1.0)/log(2.0); result = max(price[l][tmp], price[r-(1<<tmp)+1][tmp]); if(!result) cout<<"None"<<endl; else cout<<result<<endl; } return 0; }