zoukankan      html  css  js  c++  java
  • 【CodeVS3304】水果姐逛水果街Ⅰ

    Description

    水果姐今天心情不错,来到了水果街。

    水果街有n家水果店,呈直线结构,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样。

    学过oi的水果姐迅速发现了一个赚钱的方法:在某家水果店买一个水果,再到另外一家店卖出去,赚差价。

    就在水果姐窃喜的时候,cgh突然出现,他为了为难水果姐,给出m个问题,每个问题要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去,求每个问题中最多可以赚多少钱。

    Input

    第一行n,表示有n家店

    下来n个正整数,表示每家店一个苹果的价格。

    下来一个整数m,表示下来有m个询问。

    下来有m行,每行两个整数x和y,表示从第x家店出发到第y家店。

    Output

    有m行。

    每行对应一个询问,一个整数,表示面对cgh的每次询问,水果姐最多可以赚到多少钱。

    Sample Input

    10
    2 8 15 1 10 5 19 19 3 5 
    4
    6 6
    2 8
    2 2
    6 3

    Sample Output

    0
    18
    0
    14

    HINT

    0<=苹果的价格<=10^8

    0<n,m<=200000

    题解

    线段树维护区间最大值,最小值,从左往右的最大收益,从右往左的最大收益

    最大收益= max{lc最大收益,rc最大收益,lc、rc最大值-最小值}

    再也不想写线段树了 也不理栋栋了

    #include<iostream>
    #include<cstdio>
    #define N 200010
    using namespace std;
    struct node
    {
        int L,R;
        int lc,rc;
        int max,min;
        int lmx,rmx;
    }t[N*4];
    int a[N];
    int tot;
    void updata(int k)
    {
        t[k].max=max(t[t[k].lc].max,t[t[k].rc].max);
        t[k].min=min(t[t[k].lc].min,t[t[k].rc].min);
        t[k].lmx=max(t[t[k].lc].lmx,t[t[k].rc].lmx);
        t[k].lmx=max(t[k].lmx,t[t[k].rc].max-t[t[k].lc].min);
        t[k].rmx=max(t[t[k].lc].rmx,t[t[k].rc].rmx);
        t[k].rmx=max(t[k].rmx,t[t[k].lc].max-t[t[k].rc].min);
    }
    
    void build(int ll,int rr)
    {
        int cur = ++tot;
        t[cur].L = ll; t[cur].R = rr;
        if (ll!=rr)
        {
            t[cur].lc = tot+1;
            build(ll,(ll+rr)/2);
            t[cur].rc = tot+1;
            build((ll+rr)/2+1,rr);
            updata(cur);
        }
        else
            t[cur].max = t[cur].min = a[ll];
    }
    
    int query_max(int k,int ll,int rr)
    {
         if (ll<=t[k].L && rr>=t[k].R) return t[k].max;
        int mid = (t[k].L+t[k].R)/2;
        if (ll>mid) return query_max(t[k].rc,ll,rr);
        else if (rr<=mid) return query_max(t[k].lc,ll,rr);
        else return max(query_max(t[k].rc,mid+1,rr),query_max(t[k].lc,ll,mid));
    }
    
    int query_min(int k,int ll,int rr)
    {
        if (ll<=t[k].L && rr>=t[k].R) return t[k].min;
        int mid = (t[k].L+t[k].R)/2;
        if (ll>mid) return query_min(t[k].rc,ll,rr);
        else if (rr<=mid) return query_min(t[k].lc,ll,rr);
        else return min(query_min(t[k].rc,ll,rr),query_min(t[k].lc,ll,mid));
    }
    
    int query_l(int k,int ll,int rr)
    {
        int mid=(t[k].L+t[k].R)/2;
        if (ll<=t[k].L && rr>=t[k].R) return t[k].lmx;
        if (rr<=mid) return query_l(t[k].lc,ll,rr);
        else if (ll>mid) return query_l(t[k].rc,ll,rr);
        else 
        {
            int maxx = 0;
            maxx=max(query_l(t[k].lc,ll,rr),query_l(t[k].rc,ll,rr));
            maxx=max(maxx,query_max(t[k].rc,ll,rr)-query_min(t[k].lc,ll,rr));
            return maxx;
        }
    }
    int query_r(int k,int ll,int rr)
    {
        int mid=(t[k].L+t[k].R)/2;
        if (ll<=t[k].L && rr>=t[k].R) return t[k].rmx;
        if (rr<=mid) return query_r(t[k].lc,ll,rr);
        else if (ll>mid) return query_r(t[k].rc,ll,rr);
        else 
        {
            int maxx = 0;
            maxx=max(query_r(t[k].lc,ll,mid),query_r(t[k].rc,ll,rr));
            maxx=max(maxx,query_max(t[k].lc,ll,rr)-query_min(t[k].rc,ll,rr));
            return maxx;
        }
    }
    int main()
    {
        int n,m,l,r;
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        build(1,n);
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&l,&r);
            if (l<r) printf("%d
    ",query_l(1,l,r));
            else printf("%d
    ",query_r(1,r,l));
        }
    }
  • 相关阅读:
    P1121 环状最大两段子段和
    无题
    cdoj 1485 柱爷搞子串 sam treap
    自然数幂和
    Gym 100341C AVL Trees NTT
    线性筛分解质因子
    codeforces 366 Ant Man dp
    UVALive 6914 Maze Mayhem 轮廓线dp
    hdu 5790 Prefix 字典树 主席树
    莫比乌斯反演个人小结
  • 原文地址:https://www.cnblogs.com/liumengyue/p/5470116.html
Copyright © 2011-2022 走看看