hihocode #1299 打折机票

题意很简单就是给你两个数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;
}
时间: 2024-11-11 08:40:56

hihocode #1299 打折机票的相关文章

线段树之应用 ---- #1299 : 打折机票

#1299 : 打折机票 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 因为思念新宿的"小姐姐"们,岛娘计划6月份再去一趟东京,不过这次看来她需要自掏腰包.经过了几天的夜战,岛娘终于在体力耗尽之前,用Python抓下了所有6月份,上海至东京的全部共 n 张机票.现在请你帮助债台高筑的岛娘筛选出符合时间区间要求的,最贵的机票. 输入 输入数据的第一行包含两个整数 n,?m(1?≤?n,?m?≤?105),分别表示机票的总数,和询问的总数.接下来的 n 行,

hihocoder 1299 打折机票 线段树

题目链接:http://hihocoder.com/problemset/problem/1299 code: //线段树 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100005 using namespace std; int price[maxn]; int Max[maxn]; int segTree[4*maxn

HIHO Coder - 1299 打折机票

描述 因为思念新宿的"小姐姐"们,岛娘计划6月份再去一趟东京,不过这次看来她需要自掏腰包.经过了几天的夜战,岛娘终于在体力耗尽之前,用Python抓下了所有6月份,上海至东京的全部共 n 张机票.现在请你帮助债台高筑的岛娘筛选出符合时间区间要求的,最贵的机票. 输入 输入数据的第一行包含两个整数 n,?m(1?≤?n,?m?≤?105),分别表示机票的总数,和询问的总数.接下来的 n 行,每行两个整数 t,?v (1?≤?t,?v?≤?105),表示每张机票出发的时间和价格. 接下来的

题目1 : 打折机票(hihoCoder挑战赛20)

题目1 : 打折机票 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 因为思念新宿的"小姐姐"们,岛娘计划6月份再去一趟东京,不过这次看来她需要自掏腰包.经过了几天的夜战,岛娘终于在体力耗尽之前,用Python抓下了所有6月份,上海至东京的全部共 n 张机票.现在请你帮助债台高筑的岛娘筛选出符合时间区间要求的,最贵的机票. 输入 输入数据的第一行包含两个整数 n,?m(1?≤?n,?m?≤?105),分别表示机票的总数,和询问的总数.接下来的 n 行,每行

[HIHO1299]打折机票(线段树)

题目链接:http://hihocoder.com/problemset/problem/1299 线段树,按照t为下标去更新v,更新的时候要保留最大的那个. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include

题目1 : 打折机票(hihocoder 20挑战赛)

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 因为思念新宿的"小姐姐"们,岛娘计划6月份再去一趟东京,不过这次看来她需要自掏腰包.经过了几天的夜战,岛娘终于在体力耗尽之前,用Python抓下了所有6月份,上海至东京的全部共 n 张机票.现在请你帮助债台高筑的岛娘筛选出符合时间区间要求的,最贵的机票. 输入 输入数据的第一行包含两个整数 n,?m(1?≤?n,?m?≤?105),分别表示机票的总数,和询问的总数.接下来的 n 行,每行两个整数 t,?v (

留美学生最便宜机票大全 [转+整理+总结]

1.传统方法-搜! 所熟知的美国订票三大门户网站: Orbitz, Travelocity & Expedia,以及美国订票超级aggregator: Kayak, Mobissimo, SideStep, FareChase. 然后这不是重点.... Booking Buddy 强大的搜索小帮手,只用输入一次搜索信息,就能点击以下许多网站进行搜索,包含了kayak, AirTran, US Airway, Expedia, Orbitz, CheapAir, TripAdvisor, Trav

告企业丑闻作恶者,还是学学神州易桥吧!

这两天,整个互联网被魏则西之死事件来回刷屏,这个21岁本应风华正茂的大学生却因为对 "百度.三甲医院.中央台,斯坦福技术"的信任错过了治疗的最佳时机,而百度这个依靠蜂巢系统赚钱,无法有效核查是不是「新疗法」「最新技术」「国家专利」的互联网平台也被媒体和公众拉上"断头"台,这是百度今年继1月10日百度贴吧血友病吧事件后又一重大"事故".老话说的好,"苍蝇不叮无缝的蛋""好事不出门,坏事传千里",互联网一直上演

hihoCoder挑战赛20 题解

打折机票 静态区间最大值SB题 #include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) fo