WA95pts 求助
查看原帖
WA95pts 求助
371968
ningago寄寄人楼主2022/8/6 08:01

RT。斜率优化,WA on 15 求助 /kel

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>

#define N 500010
#define int long long

int dp[N];
int n,m,A,B,C;
int x[N],y[N],p[N],q[N];
struct Thing
{
    int op,id,tim;
    bool operator < (const Thing &bb)const
    {
        return tim != bb.tim ? tim < bb.tim : op > bb.op;
    }
}t[N << 1];
int opcnt;
std::vector <int> v[N];

int k0;

int Y(int k)
{
	return dp[k] + A * q[k] * q[k] - B * q[k];
}

int X(int k)
{
	return q[k];
}

bool a_better_b(int a,int b)
{
	return k0 * (X(b) - X(a)) < (Y(b) - Y(a));
}

double K(int a,int b)
{
	return (1.0 * (Y(a) - Y(b))) / (1.0 * (X(a) - X(b))); 
}

int ans = 1926081700000000ll;
signed main()
{
    scanf("%lld%lld%lld%lld%lld",&n,&m,&A,&B,&C);
    for(int i = 1;i <= m;i++)
    {
        scanf("%lld%lld%lld%lld",&x[i],&y[i],&p[i],&q[i]);
		t[++opcnt] = (Thing){0,i,p[i]};
		t[++opcnt] = (Thing){1,i,q[i]};
    }
	std::sort(t + 1,t + 1 + opcnt);
	v[1].push_back(0);
	for(int T = 1;T <= opcnt;T++)
	{
		if(t[T].op == 0)
		{
			int i = t[T].id;
			k0 = 2 * A * p[i];
			if(v[x[i]].size() == 0)
			{
				dp[i] = -1;
				continue;
			}
			int l = 0,r = v[x[i]].size() - 2;
			int j = -0x3f3f3f3f,mid;
			while(l <= r)
			{
				mid = l + r >> 1;
				if(a_better_b(v[x[i]][mid],v[x[i]][mid + 1]))
					r = mid - 1,j = v[x[i]][mid];
				else
					l = mid + 1;
			}
			if(j == -0x3f3f3f3f)
				j = v[x[i]][v[x[i]].size() - 1];
			dp[i] = dp[j] + A * (p[i] - q[j]) * (p[i] - q[j]) + B * (p[i] - q[j]) + C;
			if(y[i] == n)
			    ans = std::min(ans,dp[i] + q[i]);
		}
		else
		{
			int i = t[T].id;
			if(dp[i] == -1)
			    continue;
			int now = v[y[i]].size() - 1;
			while(now >= 1 && K(v[y[i]][now - 1],v[y[i]][now]) >= K(v[y[i]][now],i))
			{
				v[y[i]].pop_back(),now--;
			}
			v[y[i]].push_back(i);
		}
	}
	printf("%lld\n",ans);
	return 0;
}
2022/8/6 08:01
加载中...