hihocode #1299 打折机票

来源:互联网 发布:黑马程序员java课程 编辑:程序博客网 时间:2024/04/27 19:28

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



1 0
原创粉丝点击