最优贸易简化版

最优贸易简化版

题目描述
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];




1.lmid

2.mid+1r

3.l,midmid+1r

3

我是用树做的^-^

#include<iostream>
#include<cstdio>
using namespace std;
struct node{
  int a,b,c;
}tree[2000010];
int a[500010];
void dfs(int l,int r,int z){
  if (l==r){
    tree[z].a=a[l];
    tree[z].b=a[l];
    tree[z].c=0;
    return;  
  }
  int mid=(l+r)>>1;
  dfs(l,mid,z+z);
  dfs(mid+1,r,z+z+1);
  tree[z].a=min(tree[z+z].a,tree[z+z+1].a);
  tree[z].b=max(tree[z+z].b,tree[z+z+1].b);
  tree[z].c=max(tree[z+z+1].b-tree[z+z].a,max(tree[z+z].c,tree[z+z+1].c));
}
node query(int l,int r,int z,int x,int y){
  if (l>=x&&r<=y) return tree[z];
  if (l>y||r<x) return (node){1<<29,-1<<29,0};
  int mid=(l+r)>>1;
  node xx=query(l,mid,z+z,x,y);
  node yy=query(mid+1,r,z+z+1,x,y);
  return (node){min(xx.a,yy.a),max(xx.b,yy.b),max(yy.b-xx.a,max(xx.c,yy.c))};
}
int main(){
  int n,m;
  scanf("%d%d",&n,&m);
  for (int i=1;i<=n;++i) scanf("%d",&a[i]);
  dfs(1,n,1);
  while (m--){
    int x,y;
    scanf("%d%d",&x,&y);
    printf("%d\n",query(1,n,1,x,y).c);
  }
  return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值