其他分享
首页 > 其他分享> > Gym - 101806R :Recipe(分治+斜率优化)

Gym - 101806R :Recipe(分治+斜率优化)

作者:互联网

 

#include<bits/stdc++.h>
#define pii pair<ll,int>
#define mp make_pair
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=300010;
const int inf=1e9;
ll dp[maxn],F[maxn],C[maxn],L[maxn];
pii a[maxn],b[maxn]; int q[maxn],top;
ll getans(int p,int k)
{
    return dp[k]+C[p]*F[k+1]-C[p]*p;
}
void update(int p)
{
    if(top==0) return;int L=1,R=top-1,Mid;
    dp[p]=max(dp[p],getans(p,q[top]));
    while(L<=R){
        Mid=(L+R)>>1;
        ll tmp1=getans(p,q[Mid]),tmp2=getans(p,q[Mid+1]);
        if(tmp1>tmp2) R=Mid-1,dp[p]=max(dp[p],tmp1);
        else L=Mid+1,dp[p]=max(dp[p],tmp2);
    }
}
bool check(int p){
    return (dp[p]-dp[q[top]])*(F[p+1]-F[q[top-1]+1])<=
     (dp[p]-dp[q[top-1]])*(F[p+1]-F[q[top]+1]);
}
void add(int p)
{
    if(dp[p]==-inf) return ;
    if(top>0&&F[p+1]==F[q[top]+1]&&dp[p]>dp[q[top]]) top--;
    while(top>1&&check(p)) top--;
    q[++top]=p;
}
void solve(int Le,int Ri)
{
    if(Le==Ri) return ;
    int Mid=(Le+Ri)>>1;
    solve(Le,Mid);
    int tot1=0,tot2=0; top=0;
    rep(i,Le,Mid) a[++tot1]=mp(F[i+1],i);
    rep(i,Mid+1,Ri) b[++tot2]=mp(L[i],i);
    sort(a+1,a+tot1+1); sort(b+1,b+tot2+1);
    reverse(a+1,a+tot1+1); reverse(b+1,b+tot2+1);
    for(int i=1,j=1;i<=tot2;i++){
       while(j<=tot1&&b[i].first<=a[j].first){
           add(a[j].second); j++;
       }
       update(b[i].second);
    }
    solve(Mid+1,Ri);
}
int main()
{
    int N; scanf("%d",&N);
    rep(i,1,N) scanf("%lld",&F[i]),F[i]+=i;
    rep(i,1,N) scanf("%lld",&C[i]);
    rep(i,1,N) scanf("%lld",&L[i]),L[i]+=i;
    rep(i,1,N) dp[i]=-inf;
    solve(0,N);
    if(dp[N]==-inf) puts("Impossible");
    else printf("%lld\n",dp[N]);
    return 0;
}

 

标签:Le,int,Gym,Recipe,Mid,tot1,101806R,top,dp
来源: https://www.cnblogs.com/hua-dong/p/10353561.html