Problem:
Score: 200 points

Problem Statement

There are three positive integers A, B and C written on a blackboard. E869120 performs the following operation K times:

Choose one integer written on the blackboard and let the chosen integer be n. Replace the chosen integer with 2n.

What is the largest possible sum of the integers written on the blackboard after K operations?

Constraints

A, B and C are integers between 1 and 50 (inclusive).

K is an integer between 1 and 10 (inclusive).

Input

Input is given from Standard Input in the following format:

A B C
K

Output

Print the largest possible sum of the integers written on the blackboard after K operations by E869220.

Sample Input 1

5 3 11
1

Sample Output 1

30

In this sample, 5, 3, 11 are initially written on the blackboard, and E869120 can perform the operation once.

There are three choices:

Double 5: The integers written on the board after the operation are 10, 3, 11.

Double 3: The integers written on the board after the operation are 5, 6, 11.

Double 11: The integers written on the board after the operation are 5, 3, 22.

If he chooses 3., the sum of the integers written on the board afterwards is 5 + 3 + 22 = 30, which is the largest among 1. through 3.

Sample Input 2

3 3 4
2

Sample Output 2

22

E869120 can perform the operation twice. The sum of the integers eventually written on the blackboard is maximized as follows:

First, double 4. The integers written on the board are now 3, 3, 8.

Next, double 8. The integers written on the board are now 3, 3, 16.

Then, the sum of the integers eventually written on the blackboard is 3 + 3 + 16 = 22.

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::str::FromStr;
use std::io::*;
use std::cmp::*;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = AtRead::from(i);
    let abc: [usize; 3] = i.read_array();
    let k = i.read::<u32>();

    let m = abc.iter().max().unwrap();
    let r: usize = abc.iter().sum();
    let r = r - m + m * 2_usize.pow(k);

    writeln!(o, "{}", r).unwrap();
}

mod utils {
    #![allow(dead_code)]
    use super::*;
    use std::ops::*;

    pub struct AtRead<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        {$f:ident($($v:ident: $t:ident),*)} => {
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                $(
                    let $v = next(i);
                )*
                ($($v),*)
            }
        };
    }

    impl<R: BufRead> AtRead<R> {
        pub fn from(r: R) -> Self {
            AtRead {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(v1: T1, v2: T2) }
        fn_read! { read3(v1: T1, v2: T2, v3: T3) }
        fn_read! { read4(v1: T1, v2: T2, v3: T3, v4: T4) }
        fn_read! { read5(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) }

        pub fn read_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            self.read_line()
                .split(' ')
                .take(n)
                .map(|x| x.parse().ok().unwrap())
                .collect()
        }
        pub fn read_array<A: AsMut<[T]> + Default, T: FromStr>(&mut self) -> A {
            let mut a: A = Default::default();
            {
                let a: &mut [T] = a.as_mut();
                let i = &mut self.read_line().split(' ');
                for n in 0..a.len() {
                    a[n] = next(i);
                }
            }
            a
        }
    }

    fn next<'a, T: FromStr, I: std::iter::Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    #[derive(Debug, Clone, Copy)]
    pub struct ModInt(pub usize);

    const MOD_BASE: usize = 1000000007;
    const MOD_INV_POW: usize = 1000000005;

    impl ModInt {
        pub fn new(n: usize) -> Self {
            ModInt(n % MOD_BASE)
        }
        pub fn pow(self, mut exp: usize) -> Self {
            let mut b = self;
            let mut r = ModInt(1);
            while exp != 0 {
                if exp % 2 == 1 {
                    r *= b;
                }
                exp /= 2;
                b = b * b;
            }
            r
        }
        pub fn inverse_element(self) -> Self {
            self.pow(MOD_INV_POW)
        }
    }

    macro_rules! ModInt_op {
        (($ot:ident, $f:ident), ($ot_a:ident, $f_a:ident), $($rhs:ty, $e:expr,)*) => {
            $(
            impl $ot<$rhs> for ModInt {
                type Output = Self;
                fn $f(self, rhs: $rhs) -> Self {
                    Self::new(($e)(self, rhs))
                }
            }
            impl $ot_a<$rhs> for ModInt {
                fn $f_a(&mut self, rhs: $rhs) {
                    *self = Self::new(($e)(*self, rhs))
                }
            }
            )*
        }
    }

    ModInt_op!(
        (Add, add),
        (AddAssign, add_assign),
        ModInt,
        |l: ModInt, r: ModInt| l.0 + r.0,
        usize,
        |l: ModInt, r: usize| l.0 + r,
    );

    ModInt_op!(
        (Mul, mul),
        (MulAssign, mul_assign),
        ModInt,
        |l: ModInt, r: ModInt| l.0 * r.0,
        usize,
        |l: ModInt, r: usize| l.0 * r,
    );

    ModInt_op!(
        (Sub, sub),
        (SubAssign, sub_assign),
        ModInt,
        |l: ModInt, r: ModInt| MOD_BASE + l.0 - r.0,
        usize,
        |l: ModInt, r: usize| MOD_BASE + l.0 - r,
    );

    // std::cmp::Reverseと同じ
    #[derive(PartialEq, Eq)]
    pub struct RevCmp<T>(pub T);

    impl<T: PartialOrd> PartialOrd for RevCmp<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            other.0.partial_cmp(&self.0)
        }
    }
    impl<T: Ord> Ord for RevCmp<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            other.0.cmp(&self.0)
        }
    }

    pub struct PascalsTriangle<T> {
        buf: Vec<T>,
        n: usize,
    }

    impl<T: One> PascalsTriangle<T> {
        pub fn new(n: usize) -> Self {
            let mut s = PascalsTriangle {
                buf: vec![T::one()],
                n: 1,
            };
            while s.n <= n {
                let i = s.buf.len() - s.n;
                s.buf.push(T::one());
                for m in 1..s.n {
                    let v = s.buf[i + m - 1] + s.buf[i + m];
                    s.buf.push(v);
                }
                s.buf.push(T::one());
                s.n += 1;
            }
            s
        }
        pub fn get(&mut self, n: usize, m: usize) -> T {
            debug_assert!(n <= self.n);
            debug_assert!(m <= n);
            self.buf[n * (n + 1) / 2 + m]
        }
    }

    pub struct PascalsTriangleIter<T> {
        buf: Vec<T>,
    }
    impl<T: One> PascalsTriangleIter<T> {
        pub fn new(n: usize) -> Self {
            let mut s = PascalsTriangleIter {
                buf: Vec::with_capacity(n + 1),
            };
            for _ in 0..n + 1 {
                s.next();
            }
            s
        }
        pub fn next(&mut self) {
            for i in (1..self.buf.len()).rev() {
                self.buf[i] = self.buf[i] + self.buf[i - 1];
            }
            self.buf.push(T::one());
        }
        pub fn get(&self) -> &[T] {
            &self.buf
        }
    }

    pub struct ModIntFacts {
        f: Vec<ModInt>,
        rf: Vec<ModInt>,
    }
    impl ModIntFacts {
        pub fn new(n: usize) -> Self {
            let mut s = ModIntFacts {
                f: vec![ModInt(0); n + 1],
                rf: vec![ModInt(0); n + 1],
            };

            let v = ModInt(1);
            s.f[0] = v;
            for i in 1..n + 1 {
                s.f[i] = s.f[i - 1] * i;
            }
            s.rf[n] = s.f[n].inverse_element();
            for i in (1..n + 1).rev() {
                s.rf[i - 1] = s.rf[i] * i;
            }
            s
        }
        pub fn fact(&self, n: usize) -> ModInt {
            self.f[n]
        }
        pub fn comb(&self, n: usize, c: usize) -> ModInt {
            self.f[n] * self.rf[c] * self.rf[n - c]
        }
    }

    pub trait Zero: Add<Output = Self> + Sized + Copy {
        fn zero() -> Self;
    }
    pub trait One: Zero {
        fn one() -> Self;
    }

    macro_rules! impl_zero {
        ($t:ty, $e:expr) => {
            impl Zero for $t {
                fn zero() -> Self {
                    $e
                }
            }
        }
    }
    macro_rules! impl_one {
        ($t:ty, $e1:expr, $e0:expr) => {
            impl One for $t {
                fn one() -> Self {
                    $e1
                }
            }
            impl_zero!($t, $e0);
        }
    }

    impl_one!(usize, 1, 0);
    impl_one!(u32, 1, 0);
    impl_one!(i32, 1, 0);
    impl_one!(f64, 1.0, 0.0);
    impl_one!(ModInt, ModInt(1), ModInt(0));

    pub trait BinarySearchExt<T> {
        fn lower_bound_by<F: Fn(&T) -> bool>(&self, f: F) -> usize;
        fn lower_bound(&self, x: &T) -> usize;
        fn upper_bound(&self, x: &T) -> usize;
    }
    impl<T: Ord> BinarySearchExt<T> for [T] {
        fn lower_bound_by<F: Fn(&T) -> bool>(&self, f: F) -> usize {
            let mut low = 0;
            let mut high = self.len();
            while low < high {
                let mid = (low + high) / 2;
                if f(&self[mid]) {
                    high = mid;
                } else {
                    low = mid + 1;
                }
            }
            low
        }
        fn lower_bound(&self, x: &T) -> usize {
            self.lower_bound_by(|y| x <= y)
        }
        fn upper_bound(&self, x: &T) -> usize {
            self.lower_bound_by(|y| x < y)
        }
    }

    pub trait AtSliceExt<T> {
        fn rotate(&mut self, mid: usize);
    }
    impl<T> AtSliceExt<T> for [T] {
        fn rotate(&mut self, mid: usize) {
            {
                let (l, r) = self.split_at_mut(mid);
                l.reverse();
                r.reverse();
            }
            self.reverse()
        }
    }

}