zoukankan      html  css  js  c++  java
  • Traveling Merchant (2019 ICPC North American Qualifier Contest L)

    题意:

    给出一个序列,每个点都有货物其价格是周期变化的,只能从起点走向终点,每走一个点经过一天,不能再点上停留,给出起点终点问可获得的最大价值。

    思路:

    : 线段树维护 Max , Min 和 右子树的Max-左子树Min 的最大值(st) 但这样记录答案只是每个子树上的的答案,所以在查询时,还需要维护一下左右子树之间的答案
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    #define ls (now<<1)
    #define rs (now<<1|1)
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    
    #define int long long
    
    #define Bug cout<<"here
    ";
    const int maxn=2e5+10;
    
    struct node{
        int Max,Min,l,r;
    }e[20][maxn*4];
    
    int b[10][maxn];
    
    void up(node t[],int now){
    
        t[now].l=t[rs].Max-t[ls].Min;
        t[now].l=max(t[now].l,max(t[ls].l,t[rs].l));
    
        t[now].r=t[ls].Max-t[rs].Min;
        t[now].r=max(t[now].r,max(t[ls].r,t[rs].r));
    
        t[now].Max=max(t[ls].Max,t[rs].Max);
        t[now].Min=min(t[ls].Min,t[rs].Min);
    }
    
    void n_up(node &x,node a,node b)
    {
        x.l=b.Max-a.Min;
        x.l=max(x.l,max(b.l,a.l));
    
    
        x.r=a.Max-b.Min;
        x.r=max(x.r,max(b.r,a.r));
    
        x.Max=max(a.Max,b.Max);
        x.Min=min(a.Min,b.Min);
    }
    
    void built(node t[], int st,int l,int r,int now)
    {
        int mid=(l+r)>>1;
        if(l>r) return ;
        t[now].l=t[now].r=0;
        t[now].Max=t[now].Min=0;
        while(l==r)
        {
            int k=(l+st)%7;
            if(k==0) k=7;
            if(st>=7)
            {
                k=8-k;
            }
            t[now].Max=t[now].Min=b[k][l];return ;
        }
        built(t,st,lson);
        built(t,st,rson);
        up(t,now);
    
    }
    
    node query(node t[],int l,int r,int L,int R,int now)
    {
        int mid=(l+r)>>1;
        if(L<=l&&r<=R)
            return t[now];
        node ans,ans3=(node){0,0,0,0};
        if(L<=mid) ans=query(t,l,mid,L,R,now<<1);
        if(R>mid){
            node ans2=query(t,mid+1,r,L,R,now<<1|1);
            if(L<=mid) n_up(ans3,ans,ans2);
            else ans3=ans2;
        }
        else ans3=ans;
        return ans3;
    }
    
    #undef int
    int main()
    {
    #define int long long
        int n;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            int v,d;
            scanf("%lld%lld",&v,&d);
            for(int j=1;j<=4;j++)
                b[j][i]=b[7-j+1][i]=v+(j-1)*d;
        }
        for(int i=1;i<=14;i++)
            built(e[i],i-1,1,n,1);
        int t;
        scanf("%lld",&t);
        while(t--)
        {
            int l,r;
            scanf("%lld%lld",&l,&r);
            if(l<r)
            {
                int k=(9-l%7)%7;
                if(k==0) k=7;
                int ans=query(e[k],1,n,l,r,1).l;
                printf("%lld
    ",max(ans,1ll*0));
            }
            else
            {
                int k=(l%7);
                if(k==0)k=7;
                k=15-k;
                int ans=query(e[k],1,n,r,l,1).r;
                printf("%lld
    ",max(ans,1ll*0));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    使用静态全局对象自动做初始化与清理工作
    ThinkpadR617755BH1安装Mac Leopard10.5.2
    ubuntu常用快捷键
    linux常用命令
    c++对象内存模型【内存对齐】
    将ubuntu引导项加入windowsXP启动菜单中
    ISO C++委员会批准C++0x最终草案
    图片转eps格式
    Latex 点滴记录
    我是一个硬盘
  • 原文地址:https://www.cnblogs.com/minun/p/11766073.html
Copyright © 2011-2022 走看看