• 模拟赛 yjqa


    考场上怕是石乐志。

    状态设计还是很自然的,求什么设什么。

    f[i]表示前i个人安排好,电梯最早回到0层的时间

    转移的话,枚举上一次最后一个带走的是谁

    f[i]=min(max(f[j],t[i])+2*max(ak,j<k<=i))

    线段树优化

    后面的区间最大值,可以用单调栈记录,弹栈的时候,在线段树上区间赋值

    t,f都是单调不降的,所以可以边找答案边二分,一半用t[i]和ak更新。一半用f[j]和ak更新。

    记录区间最小ak,最小f[j]+aj,最小f[j],最大f[j](便于二分)

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define mid ((l+r)>>1)
    #define numb (ch^'0')
    #define ls (x<<1)
    #define rs (x<<1|1)
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=100000+5;
    int n;
    struct node{
        ll mi,fmi,vmi,fmx;
        ll ch;
        node(){
            ch=-1;
        }
    }t[8*N];
    int tim[N],a[N];
    int b[N];
    int sta[2*N],top;
    ll f[N];
    void pushup(int x){
        t[x].mi=min(t[x<<1].mi,t[x<<1|1].mi);
        t[x].fmi=min(t[x<<1].fmi,t[x<<1|1].fmi);
        t[x].vmi=min(t[x<<1].vmi,t[x<<1|1].vmi);
        t[x].fmx=max(t[ls].fmx,t[rs].fmx);
    }
    void pushdown(int x){
        if(t[x].ch==-1) return;
        t[ls].ch=t[x].ch;
        t[ls].vmi=t[x].ch;
        t[ls].mi=t[ls].fmi+2*t[ls].vmi;
        
        t[rs].ch=t[x].ch;
        t[rs].vmi=t[x].ch;
        t[rs].mi=t[rs].fmi+2*t[rs].vmi;
        t[x].ch=-1;
    }
    void upda(int x,int l,int r,int to,ll ak,ll c){
        if(l==r){
            t[x].fmi=c;
            t[x].fmx=c;
            t[x].vmi=ak;
            t[x].mi=t[x].fmi+2*t[x].vmi;
            return;
        }
        pushdown(x);
        if(to<=mid) upda(x<<1,l,mid,to,ak,c);
        else upda(x<<1|1,mid+1,r,to,ak,c);
        pushup(x);
    }
    void chan(int x,int l,int r,int L,int R,ll c){
        if(L<=l&&r<=R){
            t[x].ch=c;
            t[x].vmi=t[x].ch;
            t[x].mi=t[x].fmi+2*t[x].vmi;
            return;
        }
        pushdown(x);
        if(L<=mid) chan(x<<1,l,mid,L,R,c);
        if(mid<R) chan(x<<1|1,mid+1,r,L,R,c);
        pushup(x);
    }
    ll query(int x,int l,int r,int L,int R,ll c){
        if(L<=l&&r<=R){
            pushdown(x);
            if(t[x].fmi<t[x].fmx&&t[x].fmi<=c&&c<=t[x].fmx){
                return min(query(x<<1,l,mid,L,R,c),query(x<<1|1,mid+1,r,L,R,c));
            }
            if(t[x].fmx<=c){
                return c+2*t[x].vmi;
            }
            if(t[x].fmi>=c){
                return t[x].mi;
            }
        }
        pushdown(x);
        ll ret=0x3f3f3f3f3f3f3f3f;
        if(L<=mid) ret=min(ret,query(x<<1,l,mid,L,R,c));
        if(mid<R) ret=min(ret,query(x<<1|1,mid+1,r,L,R,c));
        return ret;
    }
    int main(){
        rd(n);
        for(reg i=2;i<=n+1;++i){
            rd(tim[i]),rd(a[i]);
        }
        for(reg i=1;i<=n;++i){
            b[i]=a[i+1];
        }
        sta[++top]=1;
        upda(1,1,n,1,b[1],0);
        for(reg i=2;i<=n+1;++i){
            //cout<<" ii "<<i<<endl;
            
            
            f[i]=query(1,1,n,1,i-1,tim[i]);
            //cout<<" f[i] "<<f[i]<<endl;
            if(i!=n+1)
            {
            upda(1,1,n,i,b[i],f[i]);
            while(top&&b[sta[top]]<b[i]){
                //cout<<sta[top]<<endl;
                chan(1,1,n,sta[top-1]+1,sta[top],b[i]);
                --top;
            }
            sta[++top]=i;
            }
        }
        printf("%lld",f[n+1]);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2018/12/24 21:59:28
    */
  • 相关阅读:
    SuperMap-iServer-单点登录功能验证(CAS)
    Oracle数据库的链接数目超标
    转载---javascript 定时器总结
    JMeter使用文档
    转载--改变ubuntu默认编码为GBK
    遥感数据下载
    Supermap iCloudManager -负载均衡
    XCode: 如何添加自定义代码片段
    imageNamed和dataWithContentsOfFile的区别(1)
    imageNamed 与 imageWithContentsOfFile的区别
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10173605.html
Copyright © 2020-2023  润新知