[Portal] (https://loj.ac/problem/3156)
=
-----
the SOL
=
meaning of problems: there are m of length n on a path of the vehicles, each vehicle has a beginning $ I $ $ x_ { i} $, end $ y_ {i} $, boarding time $ p_ {i} $, off time $ q_ {i} $. Asked from $ 1 $-point car, by transfer cost of $ n $ to reach the minimum number of points.
! [Insert Picture description here] (https://img-blog.csdnimg.cn/20190716165620585.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDQwNjU1,size_16,color_FFFFFF,t_70)
Note: Only You can get off the car on the spot.
=
-----
the SOL
=
meaning of problems: there are m of length n on a path of the vehicles, each vehicle has a beginning $ I $ $ x_ { i} $, end $ y_ {i} $, boarding time $ p_ {i} $, off time $ q_ {i} $. Asked from $ 1 $-point car, by transfer cost of $ n $ to reach the minimum number of points.
! [Insert Picture description here] (https://img-blog.csdnimg.cn/20190716165620585.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDQwNjU1,size_16,color_FFFFFF,t_70)
Note: Only You can get off the car on the spot.
----
** a, considering DP **
Although not satisfy $ x_ {i} <y_ { i} $, but time-limited, and $ p_ {i} <q_ { i} $, so there is no aftereffect.
State is difficult to find the total amount of $ O (m) $, there $ dp [i] $ $ I $ denotes a first car seat, the $ q_ {i} $ time to reach $ y_ {i} $ minimum cost
(total time $ q_ {s_ {k}} $ added last answer)
$$ DP [I] = min (DP [J] + A * (-q_ P_ {I} {J}) * (P_ {{I} -q_ j}) + B * (p_ {i} -q_ {j}) + C) $$
satisfying $ x_ {i} = y_ { j} $, $ p_ {i}> = q_ {j} $.
Equations deformation
$$ 2 * A * p_ {i } * q_ {j} + dp [i] - (A * p_ {i} * p_ {i} + B * p_ {i} + C) = dp [j] + A * q_ {j} * q_ {j} -B * q_ {j} $$
to the decision point of $ (x, y) $, there $ x = q_ {j} $ , $ y = dp [j] + A * q_ {j} * q_ {j} -B * q_ {j} $.
---
** Second, consider the decision to maintain the collection. **
For the starting and ending points of each vehicle $ u, v $, maintaining the convex hull of a set of time $ t $. Set to satisfy the decision point $ q_ {i} <= t $.
** Second, consider the decision to maintain the collection. **
For the starting and ending points of each vehicle $ u, v $, maintaining the convex hull of a set of time $ t $. Set to satisfy the decision point $ q_ {i} <= t $.
Method a: $ O (m * log m ) $
with the $ $ SET mounted $ u, v $ points to be added, in the current discussion $ x_ {i} $, the press $ q_ {i} $ ascending added.
Method two: $ O (m) $
bucket sort discharge
the decision point at $ J $ $ q_ {j} $ time, added $ y [j] $ of the convex hull. For the current point $ i $, $ p_ {i} interrogation at the time $ $ x_ {i} $ convex hull.
with the $ $ SET mounted $ u, v $ points to be added, in the current discussion $ x_ {i} $, the press $ q_ {i} $ ascending added.
Method two: $ O (m) $
bucket sort discharge
the decision point at $ J $ $ q_ {j} $ time, added $ y [j] $ of the convex hull. For the current point $ i $, $ p_ {i} interrogation at the time $ $ x_ {i} $ convex hull.
-----
CODE
=
$O(m)$
```cpp
//O(m)
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define in red()
#define cs const
#define gc getchar()
#define db double
#define rint register int
#define se second
#define fi first
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=(num<<1)+(num<<3)+(c^48);
return num*f;
}
cs int N=2e5+10;
struct pi{
ll x,y;
int id;
};
int p[N],q[N],x[N],y[N],n,m,A,B,C,head[N];
queue<int> res[3100];
vector<pi> que[N];
vector<int> d[3200];
ll dp[N],ans=1e18;
inline db slope(cs pi &a,cs pi &b){
return 1.0*(a.y-b.y)/(1.0*(a.x-b.x));
}
inline void getin(cs int &i){
int pos=y[i];
pi now=(pi){q[i],dp[i]+A*q[i]*q[i]-B*q[i],i};
while(que[pos].size()-head[pos]>=2){
int len=que[pos].size();
if(slope(que[pos][len-1],que[pos][len-2])<slope(que[pos][len-2],now))break;
que[pos].pop_back();
}
que[pos].push_back(now);
}
inline void getout(cs db &slp,cs int &pos){
while(que[pos].size()-head[pos]>=2){
if(slope(que[pos][head[pos]],que[pos][head[pos]+1])>slp)return;
++head[pos];
}
}
signed main(){
n=in,m=in,A=in,B=in,C=in;
for(rint i=1;i<=m;++i){
x[i]=in,y[i]=in,p[i]=in,q[i]=in;
}
for(rint i=1;i<=m;++i)d[p[i]].push_back(i);
que[1].push_back((pi){0,0,0});
int i;
for(rint t=0;t<=3000;++t){
while(!res[t].empty())getin(res[t].front()),res[t].pop();
int len=d[t].size();
for(rint tmp=0;tmp<len;++tmp){
int i=d[t][tmp];
int pos=x[i];
if(que[pos].size()<=head[pos])continue;
db slp=2.0*A*p[i];
getout(slp,pos);
int j=que[pos][head[pos]].id;
dp[i]=dp[j]+1ll*A*(p[i]-q[j])*(p[i]-q[j])+1ll*B*(p[i]-q[j])+C;
res[q[i]].push(i);
if(y[i]==n){
ans=min(ans,dp[i]+q[i]);
}
}
}
cout<<ans;
return 0;
}
CODE
=
$O(m)$
```cpp
//O(m)
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define in red()
#define cs const
#define gc getchar()
#define db double
#define rint register int
#define se second
#define fi first
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=(num<<1)+(num<<3)+(c^48);
return num*f;
}
cs int N=2e5+10;
struct pi{
ll x,y;
int id;
};
int p[N],q[N],x[N],y[N],n,m,A,B,C,head[N];
queue<int> res[3100];
vector<pi> que[N];
vector<int> d[3200];
ll dp[N],ans=1e18;
inline db slope(cs pi &a,cs pi &b){
return 1.0*(a.y-b.y)/(1.0*(a.x-b.x));
}
inline void getin(cs int &i){
int pos=y[i];
pi now=(pi){q[i],dp[i]+A*q[i]*q[i]-B*q[i],i};
while(que[pos].size()-head[pos]>=2){
int len=que[pos].size();
if(slope(que[pos][len-1],que[pos][len-2])<slope(que[pos][len-2],now))break;
que[pos].pop_back();
}
que[pos].push_back(now);
}
inline void getout(cs db &slp,cs int &pos){
while(que[pos].size()-head[pos]>=2){
if(slope(que[pos][head[pos]],que[pos][head[pos]+1])>slp)return;
++head[pos];
}
}
signed main(){
n=in,m=in,A=in,B=in,C=in;
for(rint i=1;i<=m;++i){
x[i]=in,y[i]=in,p[i]=in,q[i]=in;
}
for(rint i=1;i<=m;++i)d[p[i]].push_back(i);
que[1].push_back((pi){0,0,0});
int i;
for(rint t=0;t<=3000;++t){
while(!res[t].empty())getin(res[t].front()),res[t].pop();
int len=d[t].size();
for(rint tmp=0;tmp<len;++tmp){
int i=d[t][tmp];
int pos=x[i];
if(que[pos].size()<=head[pos])continue;
db slp=2.0*A*p[i];
getout(slp,pos);
int j=que[pos][head[pos]].id;
dp[i]=dp[j]+1ll*A*(p[i]-q[j])*(p[i]-q[j])+1ll*B*(p[i]-q[j])+C;
res[q[i]].push(i);
if(y[i]==n){
ans=min(ans,dp[i]+q[i]);
}
}
}
cout<<ans;
return 0;
}
```
-----
$O(m*logm)$
```cpp
//O(m*logm)
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define in red()
#define cs const
#define gc getchar()
#define db double
#define rint register int
#define se second
#define fi first
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=(num<<1)+(num<<3)+(c^48);
return num*f;
}
cs int N=2e5+10;
struct pi{
ll x,y;
int id;
};
typedef pair<int,int> pa;
int ord[N],p[N],q[N],x[N],y[N],n,m,A,B,C;
set<pa> res[N];
deque<pi> que[N];
ll dp[N],ans=1e18;
bool cmp(int a,int b){return p[a]<p[b];}
inline db slope(cs pi &a,cs pi &b){
return 1.0*(a.y-b.y)/(1.0*(a.x-b.x));
}
inline void getin(cs int &i,cs int &pos){
//cout<<"getin\n"<<i<<' '<<pos<<'\n';
while(!res[pos].empty()){
pa t=*res[pos].begin();
if(t.fi>p[i])break;
pi now=(pi){t.fi,dp[t.se]+A*t.fi*t.fi-B*t.fi,t.se};
while(que[pos].size()>=2){
pi a=que[pos].back();que[pos].pop_back();
pi that b = [pos] .back ();
if(slope(b,a)<slope(b,now)){
que[pos].push_back(a);
break;
}
}
//cout<<now.x<<' '<<now.y<<' '<<now.id<<'\n';
que[pos].push_back(now);
res[pos].erase(t);
}
// cout<<"siz: "<<que[pos].size()<<'\n';
}
inline void getout(cs db &slp,cs int &pos){
// cout<<"slp:"<<slp<<'\n';
while(que[pos].size()>=2){
pi a=que[pos].front();que[pos].pop_front();
pi b=que[pos].front();
// cout<<"slope:"<<slope(b,a)<<'\n';
if(slope(b,a)>slp){
que[pos].push_front(a);
return;
}
}
}
signed main(){
// freopen("data.in","r",stdin);
n=in,m=in,A=in,B=in,C=in;
//sf("%d%d%d%d%d",&n,&m,&A,&B,&C);
for(rint i=1;i<=m;++i){
x[i]=in,y[i]=in,p[i]=in,q[i]=in;
//sf("%d%d%d%d",&x[i],&y[i],&p[i],&q[i]);
ord[i]=i;
}
// random_shuffle(ord+1,ord+m+1);
sort(ord+1,ord+m+1,cmp);
que[1].push_back((pi){0,0,0});
for(rint o=1;o<=m;++o){
int i=ord[o];
int pos=x[i];
// cout<<"turn: "<<o<<"\n";
getin(i,pos);
if(que[pos].empty())continue;
db slp=2.0*A*p[i];
getout(slp,pos);
int j = as [pos] .front () id.;
dp[i]=dp[j]+1ll*A*(p[i]-q[j])*(p[i]-q[j])+1ll*B*(p[i]-q[j])+C;
// cout<<q[i]<<' '<<y[i]<<' '<<dp[q[i]][y[i]]<<'\n';
res[y[i]].insert(make_pair(q[i],i));
if(res[y[i]].size()>50000)getin(i,y[i]);
if(y[i]==n){
ans=min(ans,dp[i]+q[i]);
}
}
cout<<ans;
return 0;
}
```
-----
$O(m*logm)$
```cpp
//O(m*logm)
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define in red()
#define cs const
#define gc getchar()
#define db double
#define rint register int
#define se second
#define fi first
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=(num<<1)+(num<<3)+(c^48);
return num*f;
}
cs int N=2e5+10;
struct pi{
ll x,y;
int id;
};
typedef pair<int,int> pa;
int ord[N],p[N],q[N],x[N],y[N],n,m,A,B,C;
set<pa> res[N];
deque<pi> que[N];
ll dp[N],ans=1e18;
bool cmp(int a,int b){return p[a]<p[b];}
inline db slope(cs pi &a,cs pi &b){
return 1.0*(a.y-b.y)/(1.0*(a.x-b.x));
}
inline void getin(cs int &i,cs int &pos){
//cout<<"getin\n"<<i<<' '<<pos<<'\n';
while(!res[pos].empty()){
pa t=*res[pos].begin();
if(t.fi>p[i])break;
pi now=(pi){t.fi,dp[t.se]+A*t.fi*t.fi-B*t.fi,t.se};
while(que[pos].size()>=2){
pi a=que[pos].back();que[pos].pop_back();
pi that b = [pos] .back ();
if(slope(b,a)<slope(b,now)){
que[pos].push_back(a);
break;
}
}
//cout<<now.x<<' '<<now.y<<' '<<now.id<<'\n';
que[pos].push_back(now);
res[pos].erase(t);
}
// cout<<"siz: "<<que[pos].size()<<'\n';
}
inline void getout(cs db &slp,cs int &pos){
// cout<<"slp:"<<slp<<'\n';
while(que[pos].size()>=2){
pi a=que[pos].front();que[pos].pop_front();
pi b=que[pos].front();
// cout<<"slope:"<<slope(b,a)<<'\n';
if(slope(b,a)>slp){
que[pos].push_front(a);
return;
}
}
}
signed main(){
// freopen("data.in","r",stdin);
n=in,m=in,A=in,B=in,C=in;
//sf("%d%d%d%d%d",&n,&m,&A,&B,&C);
for(rint i=1;i<=m;++i){
x[i]=in,y[i]=in,p[i]=in,q[i]=in;
//sf("%d%d%d%d",&x[i],&y[i],&p[i],&q[i]);
ord[i]=i;
}
// random_shuffle(ord+1,ord+m+1);
sort(ord+1,ord+m+1,cmp);
que[1].push_back((pi){0,0,0});
for(rint o=1;o<=m;++o){
int i=ord[o];
int pos=x[i];
// cout<<"turn: "<<o<<"\n";
getin(i,pos);
if(que[pos].empty())continue;
db slp=2.0*A*p[i];
getout(slp,pos);
int j = as [pos] .front () id.;
dp[i]=dp[j]+1ll*A*(p[i]-q[j])*(p[i]-q[j])+1ll*B*(p[i]-q[j])+C;
// cout<<q[i]<<' '<<y[i]<<' '<<dp[q[i]][y[i]]<<'\n';
res[y[i]].insert(make_pair(q[i],i));
if(res[y[i]].size()>50000)getin(i,y[i]);
if(y[i]==n){
ans=min(ans,dp[i]+q[i]);
}
}
cout<<ans;
return 0;
}
```