loj 100pts 洛谷52pts 基站建设求hack
查看原帖
loj 100pts 洛谷52pts 基站建设求hack
146492
xuchenhao2008楼主2023/11/9 20:23

思路是用斜率优化+二分答案

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e6+5;
const double inf = (double)1e28;
double x[maxn]={},R[maxn]={},c[maxn]={},m,dp[maxn]={},ans = inf;
int que[maxn]={},rear =  0;
int n;
inline double getk( double &ybig, double &xbig, double &ysmall, double &xsmall ){
    return (ybig - ysmall) / (xbig - xsmall);
}
double slope[maxn]={};
int main(){
    cin >> n >> m;
    register double k; register int l , r , mid;
    for(register int i = 1; i <= n; i ++ ) scanf("%lf%lf%lf",&x[i],&R[i],&c[i]);
    int st = n;
    while(!(x[st]+R[st]>=m)) st--;
    dp[st] = dp[0] = c[st], que[rear++] = 0, que[rear++] = st, slope[1] = 0,slope[0] = inf;
    for(register int i = st-1; i >= 1; i -- ){
        k =  - ( 1.0 / 2.0 / sqrt( R[i] ) );
        l = 1, r = rear-1;
        while(l < r){
            mid = ( l + r  + 1 ) >> 1;
            if( slope[mid] <= k){
                r = mid-1;
            }else{
                l = mid;
            }
        }
        if( r == 0 ) r = 1;
        if(x[i]+R[i]>=m) dp[i] = c[i];
        else dp[i] = c[i] + dp[que[r]] - k * (x[que[r]]-x[i]);
        while( getk(dp[i],x[i],dp[que[rear-1]],x[que[rear-1]]) >= slope[rear-1] ) rear--;
        que[rear++] = i;
        if(rear-1!=1) slope[rear-1] = getk(dp[i],x[i],dp[que[rear-2]],x[que[rear-2]]);
    }
    cout << fixed << setprecision(3) << dp[1];
    return 0;
}

2023/11/9 20:23
加载中...