原题AC,这里不知道为什么错了三个点,可能是边界问题,求调
查看原帖
原题AC,这里不知道为什么错了三个点,可能是边界问题,求调
213173
小木虫楼主2022/5/10 13:44
/*
dp i代表时刻i的最小烦躁值 
dp i=dp j + A(p-j)^2 +B(p-j) + C
dp i=dp j + A(p^2+j^2-2pj) +Bp - Bj + C
dp i=dp j + AP^2 + Aj^2 -2Apj +Bp -Bj + C
(dp j - Bj + Aj^2)=(dp i - C) - Ap^2 + 2Apj - Bp
(dp j - Bj + Aj^2)=(dp i - C - Ap^2 - Bp) + (2Ap)(j)
*/
#include <bits/stdc++.h>
#define ll long long
#define double long double
using namespace std;
const int N=2e6+10;
ll n,m,A,B,C;ll res[N];
struct EDGE{int x,y,p,q;}E[N];
struct OP{int x,y;bool opt;int id;}O[N];
bool cmp(OP a,OP b){
	if(a.y!=b.y)return a.y<b.y;
	else return a.opt>b.opt;
}
struct slope_optimization{
	vector <ll> Q;int head=0;
	vector <ll> dp;vector <ll> J;
	void init(){Q.clear();dp.clear();J.clear();head=0;}
	double X(int x){return J[Q[x]];}
	double Y(int x){return dp[Q[x]]-B*J[Q[x]]+A*J[Q[x]]*J[Q[x]];}
	double slope(int x,int y){
		if(X(x)==X(y))return 1e18;
		if(Y(x)==Y(y))return -1e18;
		return (Y(y)-Y(x))/((X(y)-X(x)));
	}
	void pop_head(double K){while(head<(ll)(Q.size()-1)&&slope(head+1,head)<K)head++;}
	void insert_back(ll x,ll t){
		while(head<(ll)(Q.size()-1)){
			if((((double)t==X((ll)(Q.size()-2)))||
			(slope((ll)(Q.size()-2),(ll)(Q.size()-1)))<(double)(Y((ll)(Q.size()-2))-
			(x-B*t+A*t*t))/(double)(X((ll)(Q.size()-2))-t))&&Y((ll)(Q.size()-2))!=(x-B*t+A*t*t))
				break;
			Q.pop_back();
		}
		dp.push_back(x);J.push_back(t);Q.push_back((ll)(dp.size()-1));
	}
}s[N];
ll sol=1e18;
int main(){
	freopen("P6302_2.in","r",stdin);
	scanf("%d%d%d%d%d",&n,&m,&A,&B,&C);
	for(int i=1;i<=n;i++)s[i].init();
	for(int i=1;i<=m;i++)res[i]=1e18;
	for(int i=1;i<=m;i++)
		scanf("%d%d%d%d",&E[i].x,&E[i].y,&E[i].p,&E[i].q);
	for(int i=1;i<=m;i++){
		O[i]=(OP){E[i].x,E[i].p,0,i};O[i+m]=(OP){E[i].y,E[i].q,1,i+m};
	}
	m*=2;sort(O+1,O+1+m,cmp);
	s[1].Q.push_back(0);s[1].dp.push_back(0);
	s[1].J.push_back(0);
	for(int i=1;i<=m;i++){
		int x=O[i].x;ll p=O[i].y;int id=O[i].id;
		if(O[i].opt==0){
			s[x].pop_head(2*A*p);
			if(s[x].head<=(ll)(s[x].Q.size()-1)){
				int q=s[x].Q[s[x].head];
				res[id]=min(res[id],s[x].dp[q]+A*1ll*(p-s[x].J[q])*1ll*(p-s[x].J[q])+B*(p-s[x].J[q])+C);
			}
		}else{
			ll ans=res[id-m/2];
			if(x==n)sol=min(sol,ans+p);
			if(ans<1e18)s[x].insert_back(ans,p);
		}
	}
	printf("%lld",sol);
	return 0;
}
2022/5/10 13:44
加载中...