线性dp,后缀处理——cf1016C好题

绝对是好题

#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
#define ll long long 
ll sum1[maxn],sum2[maxn],sum3[maxn],sum[maxn],n,a[maxn][2];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i][0];
    for(int i=1;i<=n;i++)cin>>a[i][1];
    for(int i=1;i<=n;i++){//形状1的长度 
        if(i%2==0){
            sum3[i]=sum3[i-1];
            sum3[i]+=a[i][0]*(2*i-1);
            sum3[i]+=a[i][1]*(2*i-2);
        }
        else {
            sum3[i]=sum3[i-1];
            sum3[i]+=a[i][0]*(2*i-2);
            sum3[i]+=a[i][1]*(2*i-1);
        }
    }
    for(int i=n;i>=1;i--)//求一下后缀 
        sum[i]=sum[i+1]+a[i][0]+a[i][1];
    
    for(int i=n;i>=1;i--){//上面往下绕的权值 
        sum1[i]+=(2*n-1)*a[i][1];//下面的贡献是2*n-1 
        sum1[i]+=2*(i-1)*a[i][0];//下面的贡献是2*(i-1) 
        sum1[i]+=sum1[i+1]-sum[i+1]; 
    }
    for(int i=n;i>=1;i--){//下面往上绕的权值 
        sum2[i]+=2*(i-1)*a[i][1];//下面的贡献是2*(i-1)
        sum2[i]+=(2*n-1)*a[i][0];
        sum2[i]+=sum2[i+1]-sum[i+1]; 
    } 
    ll ans=0;
    for(int i=0;i<=n;i++) {
        if(i%2==0)ans=max(ans,sum3[i]+sum1[i+1]);
        else ans=max(ans,sum3[i]+sum2[i+1]);
    }
    cout<<ans<<endl; 
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/10952739.html