"EZEC-5" magic

Insert picture description here
Input:
5 2 3 102
-3 -1 1 -2 0

Output:
17
Insert picture description here
ideas: core: enumeration optimization + dichotomy.
For interval addition operations, it must be the most cost-effective
for the entire interval +1; for interval multiplication operations, it must be the most cost-effective to multiply the maximum interval by 2.
For mixing addition and multiplication, it is most cost-effective to do addition first and then multiplication.
Observing the data range s ≤ 1e9, the 31st power of 2 is about the same, so enumerate the number of multiplications and divide the number of additions by two to find the minimum cost.

//二分
//先加再乘
//枚举乘,然后加法二分
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
ll n,a,b;
ll s;
const int N=1e5+10;
ll dp[N];
ll arr[N];
ll qsm(ll a , ll b)
{
    
    
    ll ans=1,temp=a;
    while( b )
    {
    
    
        if( b & 1)  ans = (ans * temp );
        temp *= temp;
        b >>= 1;
    }
    return ans;
}
bool check( ll y ,ll x)
{
    
    
    ll maxn=-1e18;
    ll sum=0;
    //求最大字段和
    for( int i=1 ;i<=n ;i++)
    {
    
    
        if( sum < 0) sum=0;
        sum += arr[i] + y;
        maxn = max ( maxn, sum);
    }
    if( maxn<=0 )   return false;
    //写成1.0 * s qsm(2,x)会爆longlong,
	return maxn >=1.0 * s / qsm(2,x );
}
ll cal(int x)
{
    
    
    ll l = 0 , r = 3*1e9+10;
    while( l <= r )
    {
    
    
        ll mid = ( l+r )>>1;
        if( check(mid,x) )  r = mid-1;
        else l = mid+1;
    }
    return x * b + l * a;
}
signed main()
{
    
    
//    ios::sync_with_stdio(false);
//    cin.tie(0);cout.tie(0);
    cin>>n>>a>>b>>s;
    for(int i=1 ;i<=n ;i++)
        cin>>arr[i];
    ll res=1e18;
    //因为乘法最多32次,枚举乘法,二分加法即可
     for(int i=0 ;i<=32 ;i++)
     {
    
    
         res = min( res ,cal(i));
     }
     cout<<res<<endl;
}

Guess you like

Origin blog.csdn.net/m0_53688600/article/details/114966169