zoukankan      html  css  js  c++  java
  • [agc011F]Train Service Planning-[线段树优化dp+神秘思考题]

    Description

    传送门

    Solution

    请围观lhx大佬的博客(大佬写的太好了我都没有写的动力了em)

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    int n,k;
    int a[100010],b[100010];
    ll sum[100010];
    int L[100010],R[100010],t[200010];
    ll dp[100010];
    
    int tag[400010];
    void downtag(int k)
    {
        tag[k<<1]=tag[k<<1|1]=tag[k];
        tag[k]=0;
    }
    void modify(int k,int l,int r,int askx,int asky,int x)
    {
        if (askx>asky) return;
        if (askx<=l&&r<=asky) {tag[k]=x;return;}
        int mid=(l+r)/2;
        if (tag[k]) downtag(k);
        if (askx<=mid) modify(k<<1,l,mid,askx,asky,x);
        if (mid<asky) modify(k<<1|1,mid+1,r,askx,asky,x);
    }
    int query(int k,int l,int r,int x)
    {
        if (l==r) return tag[k];
        int mid=(l+r)/2;
        if (tag[k]) downtag(k);
        if (mid>=x) return query(k<<1,l,mid,x);
        else return query(k<<1|1,mid+1,r,x);
    }
    int cnt;
    ll solve(int x){
        int re=query(1,1,cnt,x);
        if (!re) return 0;
        return dp[re]+((long long)t[L[re]]-t[x]+k)%k;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            sum[i]=a[i]+sum[i-1];
            if (b[i]!=1) continue;
            if (2*a[i]>k) {puts("-1");return 0;}
        }
        for (int i=1;i<=n;i++)
        {
            if (b[i]==1)
            {
                L[i]=(-2*sum[i-1]%k+k)%k;
                R[i]=(-2*sum[i]%k+k)%k;
            }else L[i]=0,R[i]=k-1;
            t[i*2-1]=L[i],t[i*2]=R[i];
        }
        sort(t+1,t+2*n+1);
        cnt=unique(t+1,t+2*n+1)-t-1;
        for (int i=n;i;i--)
        {
            L[i]=lower_bound(t+1,t+cnt+1,L[i])-t;
            R[i]=lower_bound(t+1,t+cnt+1,R[i])-t;
            dp[i]=solve(L[i]);
            if (L[i]>R[i]) modify(1,1,cnt,R[i]+1,L[i]-1,i);
            else modify(1,1,cnt,1,L[i]-1,i),modify(1,1,cnt,R[i]+1,cnt,i);
        }
        ll ans=1e14;
        for (int i=1;i<=cnt;i++) ans=min(ans,solve(i));
        printf("%lld",ans+2*sum[n]);
    }
  • 相关阅读:
    ROS 八叉树地图构建
    2020
    Ubuntu 16.04 配置开机自动挂载 NTFS 机械硬盘!
    从 0 开始机器学习
    Ubuntu Install kitti2bag
    Ubuntu install sublime-text3
    Ubuntu 修复不能访问正确挂载机械硬盘的问题
    Ubuntu 16.04 安装 NVIDIA 显卡驱动!
    ROS 机器人技术
    phpMyAdmin getshell 学习
  • 原文地址:https://www.cnblogs.com/coco-night/p/9657775.html
Copyright © 2011-2022 走看看