#P2078. [NOI2019] 回家路线

题目描述

猫国的铁路系统中有 nn 个站点,从 1 - n1−n 编号。小猫准备从 11 号站点出发,乘坐列车回到猫窝所在的 nn 号站点。它查询了能够乘坐的列车,这些列车共 mm 班,从1 - m1−m编号。小猫将在 00 时刻到达 11 号站点。对于 ii 号列车,它将在时刻 p_ipi​ 从站点 x_ixi​ 出发,在时刻 q_iqi​ 直达站点 y_iyi​,小猫只能在时刻 p_ipi​ 上 ii 号列车,也只能在时刻 q_iqi​ 下 ii 号列车。小猫可以通过多次换乘到达 nn 号站点。一次换乘是指对于两班列车,假设分别为 uu号与 vv 号列车,若 y_u = x_vyu​=xv​ 并且 q_u \leq p_vqu​≤pv​,那么小猫可以乘坐完 uu 号列车后在 y_uyu​ 号站点等待 p_v - q_upv​−qu​ 个时刻,并在时刻 p_vpv​ 乘坐 vv 号列车。

小猫只想回到猫窝并且减少途中的麻烦,对此它用烦躁值来衡量。

  • 小猫在站点等待时将增加烦躁值,对于一次 t (t \geq 0)t(t≥0) 个时刻的等待,烦躁值将增加 At^2 + Bt + CAt2+Bt+C,其中 A, B,CA,B,C 是给定的常数。注意:小猫登上第一班列车前,即从 00 时刻起停留在 11 号站点的那些时刻也算作一次等待。
  • 若小猫最终在时刻 zz 到达 nn 号站点,则烦躁值将再增加 zz。

形式化地说,若小猫共乘坐了 kk 班列车,依次乘坐的列车编号可用序列 s_1, s_2, \cdots , s_ks1​,s2​,⋯,sk​表示。该方案被称作一条可行的回家路线,当且仅当它满足下列两个条件:

  1. x_{s1} = 1xs1​=1 , y_{sk} = nysk​=n
  2. 对于所有 j (1 \leq j < k)j(1≤j

对于该回家路线,小猫得到的烦躁值将为:

q_{s_k}+(A\times p_{s_1}^2+B\times p_{s_1}+C)+\sum_{j=1}^{k-1}(A(p_{s_{j+1}}-q_{s_j})^2+B(p_{s_{j+1}}-q_{s_j})+C)qsk​​+(A×ps1​2​+B×ps1​​+C)+j=1∑k−1​(A(psj+1​​−qsj​​)2+B(psj+1​​−qsj​​)+C)

小猫想让自己的烦躁值尽量小,请你帮它求出所有可行的回家路线中,能得到的最 小的烦躁值。题目保证至少存在一条可行的回家路线。

输入格式

第一行五个整数 n, m, A, B,Cn,m,A,B,C,变量意义见题目描述。

接下来 mm 行,第 ii 行四个整数 x_i, y_i, p_i, q_ixi​,yi​,pi​,qi​,分别表示 ii 号列车的出发站、到达站、出发时刻与到达时刻。

输出格式

输出仅一行一个整数,表示所求的答案。

样例 #1

样例输入 #1

3 4 1 5 10
1 2 3 4
1 2 5 7
1 2 6 8
2 3 9 10

Copy

样例输出 #1

94

Copy

样例 #2

样例输入 #2

4 3 1 2 3
1 2 2 3
2 3 5 7
3 4 7 9

Copy

样例输出 #2

34

Copy

提示

更多样例

您可以通过附加文件获得更多样例。

样例 3

见附加文件的 route/route3.in 与 route/route3.ans

该样例的数据类型与最终测试点 5 \sim 85∼8 一致。

样例 4

见附加文件的 route/route4.in 与 route/route4.ans

该样例的数据类型与最终测试点 11 \sim 1411∼14 一致。

样例 5

见附加文件的 route/route5.in 与 route/route5.ans

该样例的数据类型与最终测试点 18 \sim 2018∼20 一致。

样例 1 解释

共有三条可行的回家路线:

  • 依次乘坐 1,4 号列车,得到的烦躁值为:10 + (1 \times 3^2 + 5 \times 3 + 10) + (1 \times (9 - 4)^2 + 5 \times (9 - 4) + 10)= 10410+(1×32+5×3+10)+(1×(9−4)2+5×(9−4)+10)=104
  • 依次乘坐 2,4 号列车,得到的烦躁值为:10 + (1 \times 5^2 + 5 \times 5 + 10) + (1 \times (9 - 7)^2 + 5 \times (9 - 7) + 10)= 9410+(1×52+5×5+10)+(1×(9−7)2+5×(9−7)+10)=94
  • 依次乘坐 3,4 号列车,得到的烦躁值为:10 + (1 \times 6^2 + 5 \times 6 + 10) + (1 \times (9 - 8)^2 + 5 \times (9 - 8) + 10)= 10210+(1×62+5×6+10)+(1×(9−8)2+5×(9−8)+10)=102

第二条路线得到的烦躁值最小为 9494。

数据范围

对于所有测试点:2\le n\le 10^5,1\le m\le 2\times 10^5,0 \le A \le 10 , 0 \le B, C \le 10^6,1 \le x_i, y_i \le n , x_i \neq y_i , 0 \le p_i < q_i \le 10^32≤n≤105,1≤m≤2×105,0≤A≤10,0≤B,C≤106,1≤xi​,yi​≤n,xi​=yi​,0≤pi​

每个测试点的具体限制见下表:

测试点编号 nn mm A,B,CA,B,C 的特殊限制 其他特殊条件
1\sim 21∼2 \le 100≤100 =n-1=n−1 y_i=x_i+1yi​=xi​+1
3\sim 43∼4 \le 100≤100 A=B=C=0A=B=C=0
5\sim 85∼8 \le 2\times 10^3≤2×103 \le 4\times 10^3≤4×103

$x_i

 

代码:

#include 
#define N 200005
#define ll long long
#define db double
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register ll x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Max(register int a,register int b)
{
    return a>b?a:b;
}
inline ll Min(register ll a,register ll b)
{
    return a d[1005];
vectorque[N];
queue res[1005];
inline db gslope(register node a,register node b)
{
    return 1.0*(a.y-b.y)/(1.0*(a.x-b.x));
}
inline void ins(register int id)
{
    int pos=y[id];
    node now=(node){q[id],dp[id]+A*q[id]*q[id]-B*q[id],id};
    while(que[pos].size()-head[pos]>=2)
    {
        int len=que[pos].size();
        if(gslope(que[pos][len-1],que[pos][len-2])=2)
    {
        if(gslope(que[pos][head[pos]],que[pos][head[pos]+1])>slpe)
            return;
        ++head[pos];
    }
}
int main()
{
    n=read(),m=read(),A=read(),B=read(),C=read();
    for(register int i=1;i<=m;++i)
        x[i]=read(),y[i]=read(),p[i]=read(),q[i]=read(),maxT=Max(maxT,q[i]);
    for(register int i=1;i<=m;++i)
        d[p[i]].push_back(i);
    que[1].push_back((node){0,0,0});
    for(register int t=0;t<=maxT;++t)
    {
        while(!res[t].empty())
            ins(res[t].front()),res[t].pop();
        int len=d[t].size();
        for(register int k=0;k

你可能感兴趣的:(c++,算法)