zoukankan      html  css  js  c++  java
  • 测试2T3

    问题 C: 最优贸易简化版

    时间限制: 1 Sec  内存限制: 128 MB
    提交: -  解决: -
    [提交][讨论版]

    题目描述

    C国有n座城市,编号是1到n,编号为i的城市有路到编号为i+1的城市(编号为n的城市没有路到其他的城市)。
    C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。
    商人阿龙再次来到C国旅游。他还是想贩卖水晶赚取旅费,在某个城市买入,再另一个城市卖出。
    他将从编号为a的城市到编号到b的城市。请你帮他算算,最多能赚多少钱。
    注:他最多进行一次买入和一次卖出。

    输入

    第一行两个整数n和m,表示n个城市和m个询问。
    第二行n个整数,表示n座城市水晶的买入和卖出的价格。
    接下来m行,每行两个整数a、b,表示阿龙要从编号为a的城市到编号为b的城市(a<b);

    输出

    对于每个询问输出阿龙能赚多少钱。

    样例输入

    6 3
    2 1 3 6 4 5
    1 2
    2 4
    1 6
    

    样例输出

    0
    5
    5
    

    提示

    【输出输出样例解释】

    从1到2,无法赚钱。

    从2到4,在编号为2的城市买入,在编号为4的城市卖出。

    从1到6,在编号为2的城市买入,在编号为4的城市卖出。

    对于20%的数据,n和m的范围[1,500];

    对于40%的数据,n和m的范围[1,5000];

     

    【数据范围】

    对于20%的数据,n和m的范围[1,500];

    对于40%的数据,n和m的范围[1,5000];

    对于70%的数据,n和m的范围[1,50000];

    对于100%的数据,n和m的范围[1,500000];
     
    这道题第一次做的时候想的是差分一下,然后求一个最大子串和。时间复杂度O(NM),40分,加一个线段树记录一下答案,代码巨烦
    后来知道直接按题意做,线段树记录最小值,最优值,最大值。
    第一次用note的线段树

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 2000005
    int a[N];
    struct note{
    int min,max,val;
    }tree[N];
    void build(int v,int l,int r)
    {

    if(l==r)
    {
    tree[v].min=a[l];
    tree[v].max=a[l];
    tree[v].val=0;
    return;
    }

    int mid=(l+r)>>1;
    build(v<<1,l,mid);
    build(v<<1|1,mid+1,r);
    tree[v].val=max(tree[v<<1].val,max(tree[v<<1|1].val,tree[v<<1|1].max-tree[v<<1].min));
    tree[v].max=max(tree[v<<1].max,tree[v<<1|1].max);
    tree[v].min=min(tree[v<<1].min,tree[v<<1|1].min);
    }
    note search(int v,int l,int r,int x,int y)
    {
    //cout<<v<<' '<<l<<' '<<r<<' '<<x<<' '<<y<<endl;
    if(l==x&&r==y)
    return tree[v];
    int mid=(l+r)>>1;
    if(mid<x)return search(v<<1|1,mid+1,r,x,y);else
    if(y<=mid) return search(v<<1,l,mid,x,y);else
    {
    //return max(tree[v<<1],max(tree[v<<1|1],treemax[v<<1|1]-treemin[v<<1]));
    note nt1,nt2=search(v<<1,l,mid,x,mid),nt3=search(v<<1|1,mid+1,r,mid+1,y);
    nt1.val=max(nt2.val,max(nt3.val,nt3.max-nt2.min));
    nt1.min=min(nt2.min,nt3.min);
    nt1.max=max(nt2.max,nt3.max);
    return nt1;
    }
    }
    int n,m;
    int main()
    {
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
    int l,r;
    scanf("%d %d",&l,&r);
    printf("%d ",search(1,1,n,l,r).val);
    }
    return 0;
    }

  • 相关阅读:
    一个人事工资模块
    Delete From 带 inner join
    打开SQL AnyWhere *.db数据库
    开启查询IO操作统计
    一个大数据量表访问优化联动下拉框查询优化
    一个简单的配置文件读取类
    MSSQL2005 双机热备说明
    数据库镜像
    GridView + ObjectDatasource 的一个范例代码
    往带自增长列的数据表中导数据
  • 原文地址:https://www.cnblogs.com/dancer16/p/6873343.html
Copyright © 2011-2022 走看看