题意很简单就是给你两个数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;
}