\[dp[id]=Min(dp[j]+A(p_{id}-q_j)^2+B(p_{id}-q_j)+C)(id,j \in [1,m],q_j<=p_{id},v[j]=u[id])\]node
\[dp[j]+Aq_j^2-Bq_j=2Ap_iq_j+dp[i]-Ap_i^2-Bp_i-C\]c++
#include <bits/stdc++.h> #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<b?a:b; } struct node{ ll x,y; int id; }; int n,m,A,B,C,maxT=0; int x[N],y[N],p[N],q[N],head[N]; ll ans=1926081700000000ll,dp[N]; vector<int> d[1005]; vector<node>que[N]; queue<int> 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])<gslope(que[pos][len-2],now)) break; que[pos].pop_back(); } que[pos].push_back(now); } inline void del(register db slpe,register int pos) { while(que[pos].size()-head[pos]>=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<len;++k) { int id=d[t][k]; int pos=x[id]; if(que[pos].size()==head[pos]) continue; db slpe=2.0*A*p[id]; del(slpe,pos); int j=que[pos][head[pos]].id; dp[id]=dp[j]+1ll*A*(p[id]-q[j])*(p[id]-q[j])+1ll*B*(p[id]-q[j])+C; res[q[id]].push(id); if(y[id]==n) ans=Min(ans,dp[id]+q[id]); } } write(ans); return 0; }