#!/usr/bin/env python3

import math

class SolverFast:
# a,b=#laps, x,y=#repeted times this strategy
# a*x+b*y = n
    def get_race_strategy(self, pit_stops, number_laps):
        different_tiers = pit_stops +1
        if number_laps % different_tiers==0:
            # Same length on every tiers
            a = number_laps/different_tiers
            x = different_tiers
            b = 0
            y = 0
            return ((a,x), (b,y))
        else:
            # To different set of tier lengths
            a = math.ceil(number_laps/different_tiers)
            b = math.floor(number_laps/different_tiers)
            x = number_laps - b*different_tiers
            y = a*different_tiers-number_laps
            return ((a,x),(b,y))
        

        """pit_time, base, tear,total_laps = 
        time_spent_pitting = pit_time*(total_laps/number_of_diff_tiers-1) # We don't pit when we hit goal
        base_time = base*total_laps
        additional_time_due_to_wear = (lap_length-1)*lap_length*(2*lap_length-1)*total_laps*tear
        total_time = time_spent_pitting+base_time+additional_time_due_to_wear
        """



    def total_round_time(self,total_number_of_pits,task_data):
        """
        First, find the best split of racestrategy. 

        Then calulate the time spent racing each of them.

        return the combined result
        """
        (pit_time,base_time, tear_factor, total_number_laps) = task_data
        ((a,x),(b,y)) = self.get_race_strategy(pit_stops=total_number_of_pits,
                                        number_laps= total_number_laps)

        time_spent_pitting = pit_time = total_number_of_pits*pit_time
        time_spent_first_part = self.time_spent_in_segment(different_tiers=x,laps_each_tier=a,
                                        base=base_time,tier_degrading=tear_factor)
        #print(f"x:{x}, a:{a}")
        #print(f"first:{time_spent_first_part}")
        if b==0 and y==0:
            return time_spent_first_part + time_spent_pitting

        time_spent_second_part = self.time_spent_in_segment(different_tiers=y,laps_each_tier=b, 
                                        base=base_time, tier_degrading=tear_factor)
        #print(f"second:{time_spent_second_part}")
        #print(f"pitting:{time_spent_pitting}")

        return time_spent_first_part + time_spent_second_part + time_spent_pitting


    def time_spent_in_segment(self, different_tiers,laps_each_tier, base, tier_degrading):
        """
        Do some math, get om answers.
        P = different_tiers -1 = pitstops
        p = pit_stop_time
        N = Total laps
        J = N/P distance each tier
        r = base_time
        b = tier_degrading


        unoptimized formula used: 
        f(*) = P*p + (P+1)*sum(b*i + r)[i=0 to i=J-1]
        """
        base_time = different_tiers*laps_each_tier*base 
        extra_time_due_to_tier_wear = different_tiers*tier_degrading*(laps_each_tier-1)*(laps_each_tier)/2
        total_time = base_time + extra_time_due_to_tier_wear
        return total_time







    # start: low = 1, high = laps / 2
    def binary_search(self,low, high, task_data):
        if low >=high:
            return low, self.total_round_time(low, task_data)
        midle = high+low//2
        midle_low_time= self.total_round_time(midle-1,task_data)
        midle_high_time = self.total_round_time(midle+1,task_data)
        midle_time = self.total_round_time(midle, task_data)
        if midle_time <= midle_low_time and midle_time <= midle_high_time:
            return midle, midle_time
        if midle_low_time <= midle_high_time:
            return self.binary_search(low, midle-1, task_data)

        else:
            return self.binary_search(midle+1, high, task_data)


    def binary_search_non_req(self,low,high,task_data):
        while(low < high):
            midle = (high+low)//2
            if midle == low:
                high_time = self.total_round_time(high, task_data)
                low_time = self.total_round_time(low, task_data)
                if low_time < high_time:
                    return (low, low_time)
                else:
                    return (high, high_time)
            midle_low_time= self.total_round_time(midle-1,task_data)
            midle_high_time = self.total_round_time(midle+1,task_data)
            midle_time = self.total_round_time(midle, task_data)
            if midle_time <= midle_low_time and midle_time <= midle_high_time:
                return midle, midle_time
            if midle_low_time <= midle_high_time:
                high= midle-1

            else:
                low = midle+1
        return low, self.total_round_time(low, task_data)

def read_input():
    n, p, base_time, tear_factor = map(int, input().split())
    return n,p,base_time, tear_factor

def main():
    laps, pit_time, base_time, tear_factor = read_input()
    task_data = (pit_time,base_time, tear_factor, laps)
    solver = SolverFast()
    best_number_pit_stops, time = solver.binary_search_non_req(0,laps-1, task_data) 
    #print(best_number_pit_stops)
    print(int(round(time)))

    # Yolo no stop lets go!
if "__main__" == __name__:
    main()