思路

模意义

这题真tm有意思

我上下楼梯了半天做出来的qwq

首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行

这时,我们只需要考虑两边的两辆车就好了。

定义一些称呼:

上行:从$0$~$n$的车

下行:从$n$~$0$的车

定义数组:

$p[i](i=0...n)$表示上行车在站台$i$的停车时长

$q[i](i=0...n)$表示下行车在站台$i$的停车时长

$a[i](i=0...n-1)$表示第$i$的站台与第$i+1$个站台中间的行驶时间(也就是题目给定的数组)

我们再定义$S(a,i)$表示数组$a$从零开始到$i$的前缀和函数,即:

$S(a,i)=\sum_{j=0}^i a[j]$

区间不交

考虑两辆车合法的情况。显然,他们俩在每一段铁路上行驶的时间是一个区间。双向铁路不用管,一定合法,我们发现如果单向铁路上合法,那么上下行的车在某一段单向铁路上行驶的区间肯定不相交

我们把上下行车辆在铁路$k$上的行驶时间区间写出来:

上行:$(S(a,i-1)+S(p,i),S(a,i)+S(p,i))$

下行:$(-S(a,i-1)-S(q,i),-S(a,i)-S(q,i))$

注意这里的下行部分是一个很巧妙的转化:因为我们在模意义下运算,所以下行部分本来应该是用两个后缀和加在一起的,但是这样上下行式子不统一

所以,我们把后缀和看做总和减掉前缀和,那么总和可以调整为$K$的倍数,就没掉了,所以就是负的前缀和

这两段区间如果不交,那么显然任意一个端点不在另外一个区间里面

这样我们可以得到一批不等式,大概类似于这个形式:

$-2S(a,i-1)>S(p,i)+S(q,i)>-S(a,i-1)-S(a,i)$

最终化一下,可以得到这个结论:

$S(p,i)+S(q,i) \notin (-2\ast S(a,i),-2\ast S(a,i-1))$

可以看到对于每个$i$,不可选的区间是固定的

那么我们考虑在模$K$的意义下,右边这个区间的补集,我们设它为$[L[i],R[i]]$

$S(p,i)+S(q,i) \in [L[i],R[i]]$

问题变化

我们发现,本题的答案,实际上就是最小化的$S(p,n)+S(q,n)+2\ast S(a,n)$,等价于最小化$S(p,n)+S(q,n)$

这样,我们可以把问题转化为:

给定$n$个区间,任选起点,走$n$步,第$i$步需要落在区间$i$中,求最小总路径长度

注意这里的“走”实际上,从一个大的走向小的,是要走到$K$,然后从$0$再出来(因为我们是模$K$意义下的)

这样就可以变成一个$DP$问题了

线段树优化$DP$

我们现在考虑新的这个问题,显然可以使用$dp$来做

首先有一个贪心结论:如果起点已经确定了,那么每次需要走的时候,走到下一个区间的左端点肯定最优,证明显然

那么我们可以先预处理出来在每个起点出发后,一直走左端点直到走完,我需要的最小距离

预处理

定义$dp[i]$表示对于区间$[L[i],R[i]]$的左端点$L[i]$而言,一直走左端点到$n$的最短路径

那么我们倒着从$n$到$1$推这个$dp$

每推完一个$dp[i]$,我们就把区间$[L[i],R[i]]$的补集在线段树上的值,覆盖为$i$

然后推$dp[i]$时,每次查询$L[i]$位置的线段树上的值,设这个值是$j$

那么显然,编号在区间$[i,j-1]$中的所有区间都覆盖了$L[i]$这个点

所以直接在这里不动,就可以走完这些区间了

那么我们用$dp[j]+dis(L[i],L[j])$来更新$dp[i]$

然后再覆盖区间,就完成了$dp$预处理过程

统计答案!

最后一步,我们枚举所有出现的$L[i]$和$R[i]$,并把它们作为起点,求出答案。

显然如果不选这些端点的话,答案只会更劣

统计出的答案,就是原来问题中的$S(q,n)+$S(p,n)$,也就是我们要最小化的东西

加上$2S(a,n)$输出即可

做完啦~

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#define ll long long
using namespace std;
inline ll read(){
    ll re=0,flag=1;char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') flag=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    return re*flag;
}
ll n,K,cnt,a[200010],b[200010],tmp[500010],seg[500010],L[200010],R[200010],dp[200010],sum[200010];
void push(ll num){
    if(!seg[num]) return;
    seg[num<<1]=seg[num<<1|1]=seg[num];
    seg[num]=0;
}
void change(ll l,ll r,ll ql,ll qr,ll num,ll val){
    if(ql>qr) return;
    if(l>=ql&&r<=qr){seg[num]=val;return;}
    push(num);
    ll mid=(l+r)>>1;
    if(mid>=ql) change(l,mid,ql,qr,num<<1,val);
    if(mid<qr) change(mid+1,r,ql,qr,num<<1|1,val);
}
ll query(ll l,ll r,ll num,ll pos){
    if(l==r) return seg[num];
    push(num);
    ll mid=(l+r)>>1;
    if(mid>=pos) return query(l,mid,num<<1,pos);
    else return query(mid+1,r,num<<1|1,pos);
}
ll ask(ll pos){
    ll choose=query(1,cnt,1,pos);
    if(!choose) return 0;
    return (dp[choose]+(tmp[L[choose]]-tmp[pos]+K)%K);
}
ll erfen(ll val){
    ll l=1,r=cnt,mid;
    while(l<r){
        mid=(l+r)>>1;
        if(tmp[mid]>=val) r=mid;
        else l=mid+1;
    }
    assert(val==tmp[l]);
    return l;
}
int main(){
    n=read();K=read();ll i;
    for(i=1;i<=n;i++) {
        a[i]=read();b[i]=read();
        sum[i]=(sum[i-1]+a[i]);
        if(b[i]==2) continue;
        if(2*a[i]>K){
            puts("-1");return 0;
        }
    }
    for(i=n;i>=1;i--){
        if(b[i]==1){
            L[i]=(-2ll*sum[i-1]%K+K)%K;
            R[i]=(-2ll*sum[i]%K+K)%K;
        }
        else L[i]=0,R[i]=K-1;
        tmp[++cnt]=L[i],tmp[++cnt]=R[i];
    }
    sort(tmp+1,tmp+cnt+1);
    cnt=unique(tmp+1,tmp+cnt+1)-tmp-1;
    for(i=n;i>=1;i--){
        L[i]=erfen(L[i]);
        R[i]=erfen(R[i]);
        dp[i]=ask(L[i]);
        if(L[i]>R[i]) change(1,cnt,R[i]+1,L[i]-1,1,i);
        else change(1,cnt,1,L[i]-1,1,i),change(1,cnt,R[i]+1,cnt,1,i);
    }
    ll ans=dp[1];
    for(i=cnt;i>=1;i--) ans=min(ans,ask(i));
    printf("%lld\n",ans+sum[n]*2ll);
}

[AGC011F] Train Service Planning [线段树优化dp+思维]的更多相关文章

  1. [Agc011F] Train Service Planning

    [Agc011F] Train Service Planning 题目大意: 有n+1个车站,n条轨道,第i条轨道联通i-1和i车站,通过它要花a[i]时间,这条轨道有b[i]=1或2条车道,也就是说 ...

  2. Codeforces Round #426 (Div. 2) D 线段树优化dp

    D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  3. BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】

    BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...

  4. 【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp

    题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a varian ...

  5. POJ 2376 Cleaning Shifts (线段树优化DP)

    题目大意:给你很多条线段,开头结尾是$[l,r]$,让你覆盖整个区间$[1,T]$,求最少的线段数 题目传送门 线段树优化$DP$裸题.. 先去掉所有能被其他线段包含的线段,这种线段一定不在最优解里 ...

  6. 洛谷$P2605\ [ZJOI2010]$基站选址 线段树优化$dp$

    正解:线段树优化$dp$ 解题报告: 传送门$QwQ$ 难受阿,,,本来想做考试题的,我还造了个精妙无比的题面,然后今天讲$dp$的时候被讲到了$kk$ 先考虑暴力$dp$?就设$f_{i,j}$表示 ...

  7. D - The Bakery CodeForces - 834D 线段树优化dp···

    D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...

  8. 4.11 省选模拟赛 序列 二分 线段树优化dp set优化dp 缩点

    容易想到二分. 看到第一个条件容易想到缩点. 第二个条件自然是分段 然后让总和最小 容易想到dp. 缩点为先:我是采用了取了一个前缀最小值数组 二分+并查集缩点 当然也是可以直接采用 其他的奇奇怪怪的 ...

  9. Codeforces 1603D - Artistic Partition(莫反+线段树优化 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 学 whk 时比较无聊开了道题做做发现是道神题( 介绍一种不太一样的做法,不观察出决策单调性也可以做. 首先一个很 trivial 的 o ...

随机推荐

  1. 使用nodejs代码在SAP C4C里创建Individual customer

    需求:使用nodejs代码在SAP Cloud for Customer里创建Individual customer实例. 代码: var createAndBind = require('../je ...

  2. web服务器、app(应用)服务器、DB后端性能瓶颈和分析

    性能测试day07_性能瓶颈和分析 https://www.cnblogs.com/leixiaobai/p/9463748.html 其实如果之前都做的很到位的话,那么再加上APM工具(dynaTr ...

  3. oracle中PLSQL存储过程中如何使用逗号分隔的集合(逗号分隔字符串转换为一个集合)

    原文: https://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_claus ...

  4. UVa 10491 - Cows and Cars(全概率)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. 【[USACO15JAN]草鉴定Grass Cownoisseur】

    这大概是我写过的除了树剖以外最长的代码了吧 首先看到有向图和重复经过等敏感词应该能想到先tarjan后缩点了吧 首先有一个naive的想法,既然我们要求只能走一次返回原点,那我们就正着反着建两遍图,分 ...

  6. 微信公众号支付IOS系统能够唤起,安卓系统不能唤起的问题解决

    前言 之前系统内做过要给微信支付程序,只不过鉴于业务应用场景,大部分都是使用业务内的金币兑换产品,没有实际用到支付功能.后来运营小哥哥说他的手机不能唤起支付.于是乎我查询了一下资料,发现了这么个问题. ...

  7. TCP/IP模型 & 5层参考模型

    OSl参考模型与TCP/IP参考模型相同点: 1.都分层 2.基于独立的协议栈的概念 3.可以实现异构网络互联

  8. 20181030NOIP模拟赛T3

    2017种树 2017共有N棵树从0到N-1标号.现要把这些树种在一条直线上,第i棵树的种植位置X[i]如下确定: X[0] = X[0] MOD L: X[i] = (X[i-1]*A+B) MOD ...

  9. STL笔记

    STL的基本概念: 1-容器:是可容纳各种类型的数据结构,是 类模板. 2-迭代器:是用于依次存放容器中的元素,类似指针. 3-算法: 是用于操作容器中元素的 函数模板. sort() 用来对 vec ...

  10. CentOS 6.8安装Ceph

    机器规划 IP 主机名 角色 10.101.0.1 ceph01 mon admin mds 10.101.0.2 ceph02 ods 10.101.0.3 ceph03 ods 10.101.0. ...