先桶排,再vector维护斜率优化dp。感觉应该没问题吧?谢谢。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+1e4,M=1e6+1e5;
int n,m,t,l[N],r[N];
ll A,B,C,f[M],ans=4e18;
struct nod{
int x,y,w; ll p,q;
}T,a[M]; vector<nod>P[41000],PP[41000];
struct nodd{
ll x,y;
}D; vector<nodd>Q[N];
int Max(int x,int y){return x>y?x:y;}
ll Min(ll x,ll y){return x<y?x:y;}
int rd(){
int s=0,ff=1;
char w=getchar();
while(!isdigit(w))
ff^=w=='-',w=getchar();
while(isdigit(w))
s=s*10+w-'0',w=getchar();
return ff?s:-s;
}
double Qiuk(nodd X,nodd Y){
return 1.0*(X.y-Y.y)/(X.x-Y.x);
}
int main(){
n=rd(); m=rd(); A=rd(); B=rd(); C=rd();
for(int i=1;i<=n;i++) l[i]=0,r[i]=-1;
for(int i=1;i<=m;i++){
a[i].x=rd(),a[i].y=rd(),a[i].p=rd(),a[i].q=rd(),a[i].w=i;
P[a[i].p].push_back(a[i]); PP[a[i].q].push_back(a[i]);
t=Max(t,(int)a[i].q);
} D.x=0; D.y=0; ++r[1]; Q[1].push_back(D);
memset(f,127,sizeof(f));
for(int i=0;i<=t;i++){
for(int j=0;j<PP[i].size();j++){ T=PP[i][j];
if(f[T.w]>4e18) continue ;
D.x=2*A*T.q; D.y=f[T.w]+A*T.q*T.q-B*T.q-T.q;
while(l[T.y]<r[T.y]&&Qiuk(Q[T.y][r[T.y]],Q[T.y][r[T.y]-1])>=Qiuk(D,Q[T.y][r[T.y]])) r[T.y]--,Q[T.y].pop_back();
++r[T.y]; Q[T.y].push_back(D);
}
for(int j=0;j<P[i].size();j++){ T=P[i][j];
while(l[T.x]<r[T.x]&&Qiuk(Q[T.x][l[T.x]+1],Q[T.x][l[T.x]])<=T.p) l[T.x]++;
if(l[T.x]<=r[T.x]) f[T.w]=Q[T.x][l[T.x]].y-Q[T.x][l[T.x]].x*T.p+A*T.p*T.p+B*T.p+C+T.q;
}
}
for(int i=1;i<=m;i++) if(a[i].y==n) ans=Min(ans,f[i]);
printf("%lld\n",ans); return 0;
}