using System;
using System.IO;
using System.Text;

namespace Iterated_Linear_Function
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static int mod = 1000000007;

        private static void Main(string[] args)
        {
            long A = Next(), B = Next(), n = Next(), x = Next();

            var nn = new[,] {{A, 0}, {B, 1}};
            long[,] res = Pow(nn, n);

            writer.WriteLine(((res[0, 0]*x)%mod + res[1, 0])%mod);
            writer.Flush();
        }

        private static long[,] Pow(long[,] a, long k)
        {
            var r = new long[,] {{1, 0}, {0, 1}};
            while (k > 0)
            {
                if ((k & 1) == 1)
                {
                    r = Mult(r, a);
                }
                a = Mult(a, a);
                k >>= 1;
            }
            return r;
        }

        private static long[,] Mult(long[,] a, long[,] b)
        {
            return new[,]
                       {
                           {
                               ((a[0, 0]*b[0, 0])%mod + (a[0, 1]*b[1, 0])%mod)%mod,
                               ((a[0, 0]*b[0, 1])%mod + (a[0, 1]*b[1, 1])%mod)%mod
                           },
                           {
                               ((a[1, 0]*b[0, 0])%mod + (a[1, 1]*b[1, 0])%mod)%mod,
                               ((a[1, 0]*b[0, 1])%mod + (a[1, 1]*b[1, 1])%mod)%mod
                           }
                       };
        }

        private static long Next()
        {
            int c;
            long res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}

using System;

namespace Temp
{
    class Program
    {
        static void Main(string[] args)
        {
            var inputs = Console.ReadLine().Split();
            var a = int.Parse(inputs[0]);
            var b = int.Parse(inputs[1]);
            var n = long.Parse(inputs[2]);
            var x = int.Parse(inputs[3]);

            //res = a^n * x + (a^(n-1) + a^(n-2) + ... + a + 1) * b
            //res = a^n * x + (a^n - 1)/(a - 1) * b

            var mod = 1000000007;
            long an = ModPow(a, n, mod);

            long res;
            if (a > 1)
            {
                res = (an - 1 + mod) % mod;
                long den = (a - 1 + mod) % mod;
                long denInv = ModPow(den, mod - 2, mod);    //Modular multiplicative inverse computation using Euler's theorem
                res *= denInv; res %= mod;
            }
            else res = n % mod; //Edgecase: a = 1
            res *= b; res %= mod;
            res += (an * x) % mod; res %= mod;

            Console.WriteLine(res);
        }

        static int ModPow(long b, long exp, int mod)
        {
            var res = 1L;
            while (exp > 0)
            {
                if (exp % 2 == 1) { res *= b; res %= mod; }
                exp /= 2;
                b *= b; b %= mod;
            }
            return (int)res;
        }
    }
}

using System;
using System.Numerics;

namespace Temp
{
    class Program
    {
        static void Main(string[] args)
        {
            var inputs = Console.ReadLine().Split();
            var a = BigInteger.Parse(inputs[0]);
            var b = BigInteger.Parse(inputs[1]);
            var n = BigInteger.Parse(inputs[2]);
            var x = BigInteger.Parse(inputs[3]);

            //res = a^n * x + (a^(n-1) + a^(n-2) + ... + a + 1) * b
            //res = a^n * x + (a^n - 1)/(a - 1) * b

            var mod = new BigInteger(1000000007);
            var an = BigInteger.ModPow(a, n, mod);

            BigInteger res;
            if (a > 1)
            {
                res = (an - 1 + mod) % mod;
                var den = (a - 1 + mod) % mod;
                var denInv = BigInteger.ModPow(den, mod - 2, mod);    //Modular multiplicative inverse computation using Euler's theorem
                res *= denInv; res %= mod;
            }
            else res = n % mod; //Edgecase: a = 1
            res *= b; res %= mod;
            res += (an * x) % mod; res %= mod;

            Console.WriteLine(res);
        }
    }
}

using System;

namespace Temp
{
    class Program
    {
        static void Main(string[] args)
        {
            var inputs = Console.ReadLine().Split();
            var a = int.Parse(inputs[0]);
            var b = int.Parse(inputs[1]);
            var n = long.Parse(inputs[2]);
            var x = int.Parse(inputs[3]);

            var mod = 1000000007;
            long an = ModPow(a, n, mod);
            long res = (an * x) % mod;

            long nom;
            if (a > 1)
            {
                nom = (an - 1 + mod) % mod;
                long den = (a - 1 + mod) % mod;
                long denInv = ModPow(den, mod - 2, mod);
                nom *= denInv; nom %= mod;
            }
            else nom = n % mod;
            nom *= b; nom %= mod;
            res += nom; res %= mod;

            Console.WriteLine(res);
        }

        static int ModPow(long b, long exp, int mod)
        {
            var res = 1L;
            while (exp > 0)
            {
                if (exp % 2 == 1) { res *= b; res %= mod; }
                exp /= 2;
                b *= b; b %= mod;
            }
            return (int)res;
        }
    }
}

using System;
using System.Globalization;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace Codeforces
{
    class Program : ProgramBase
    {
        private const long commonMod = 1000000007;

        static void Main(string[] args)
        {
            var p = new Program();
            var x = p.Get();
            p.Out(x);
        }

        object Get()
        {
            checked
            {
                var a = ReadLongToken();
                var b = ReadLongToken();
                var n = ReadLongToken();
                var x = ReadLongToken();
                if (a == 1)
                    return (x + b * (n  % commonMod)) % commonMod;
                var first = (FastPow(a, n, commonMod) * x) % commonMod;
                var q1 = (FastPow(a, n, commonMod) + commonMod - 1);
                var q2 = FastPow(a - 1, commonMod - 2, commonMod);
                var second = b * ((q1 * q2) % commonMod);
                return (first + second) % commonMod;
            }
        }

        long FastPow(long b, long pow, long mod)
        {
            if (pow == 0)
                return 1;
            if (pow == 1)
                return b;
            if (pow % 2 == 0)
                return FastPow((b * b) % mod, pow / 2, mod);
            return (FastPow(b, pow - 1, mod) * b) % mod;
        }

        //object Get()
        //{
        //    checked
        //    {
        //        var n = ReadIntToken();
        //        var k = ReadIntToken();
        //        var table = new bool[n, n];
        //        for (int i = 0; i < n; i++)
        //        {
        //            var input = Read();
        //            for (int j = 0; j < n; j++)
        //                table[i, j] = input[j] == '.';
        //        }
        //        var cells = BFS(table);
        //    }
        //}
        //Cell[,] BFS(bool[,] input)
        //{
        //    var n = input.GetLength(0);
        //    var cells = new Cell[n, n];
        //    var visited = new bool[n, n];
        //    var componentIndex = 0;
        //    for (int i = 0; i < n; i++)
        //    {
        //        for (int j = 0; j < n; j++)
        //        {
        //            if (!visited[i, j] && input[i, j])
        //                BFS(i, j, cells, input, visited, componentIndex);
        //        }
        //    }
        //}

        //void BFS(int i, int j, Cell[,] cells, bool[,] input, bool[,] visited, int ccIndex)
        //{
        //    var n = input.GetLength(0);
        //    for
        //}

        struct Cell
        {
            int CCNumber { get; set; }
        }

        class Automata
        {
            bool[] terminals;
            public int sigma;
            public int len;
            public int[,] jumps;

            public void Create()
            {
                var a = ReadInts();
                len = a[0];
                sigma = a[2];
                var ts = ReadInts();
                terminals = new bool[len];
                for (int i = 0; i < ts.Length; i++)
                    terminals[ts[i]] = true;
                jumps = new int[len, sigma];
                for (int i = 0; i < len * sigma; i++)
                {
                    var b = Console.ReadLine().Split(' ');
                    jumps[Convert.ToInt32(b[0]), b[1][0] - 'a'] = Convert.ToInt32(b[2]);
                }
            }
            protected int[] ReadInts()
            {
                return Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
            }

            public bool IsTerminal(int s)
            {
                return terminals[s];
            }
        }
    }

    abstract class ProgramBase
    {
        bool? prod = null;
        StreamReader f;
        Queue<string> tokens;
        protected string FileName { private get; set; }

        protected string Read()
        {
            if (f == null)
                f = string.IsNullOrEmpty(FileName)
                    ? new StreamReader(Console.OpenStandardInput())
                    : new StreamReader((GetProd() ? "" : "c:\\dev\\") + FileName);
            return f.ReadLine();
        }

        protected int ReadInt()
        {
            return int.Parse(Read());
        }

        protected int ReadIntToken()
        {
            if (tokens == null || tokens.Count == 0)
                tokens = new Queue<string>(Read().Split(' '));
            return int.Parse(tokens.Dequeue());
        }

        protected int[] ReadInts()
        {
            var tokens = Read().Split(' ');
            var result = new int[tokens.Length];
            for (int i = 0; i < tokens.Length; i++)
                result[i] = int.Parse(tokens[i]);
            return result;
        }

        protected long ReadLongToken()
        {
            if (tokens == null || tokens.Count == 0)
                tokens = new Queue<string>(Read().Split(' '));
            return long.Parse(tokens.Dequeue());
        }

        protected long ReadLong()
        {
            return Convert.ToInt64(Read());
        }

        protected long[] ReadLongs()
        {
            var tokens = Read().Split(' ');
            var result = new long[tokens.Length];
            for (int i = 0; i < tokens.Length; i++)
                result[i] = long.Parse(tokens[i]);
            return result;
        }

        public void Out(object r)
        {
            if (string.IsNullOrEmpty(FileName))
                Console.WriteLine(r);
            else if (GetProd())
                File.WriteAllText(FileName, r.ToString());
            else
                Console.WriteLine(r);
        }

        private bool GetProd()
        {

            if (!prod.HasValue)
                try
                {
                    prod = Environment.MachineName != "RENADEEN-W7";
                }
                catch (Exception)
                {
                    prod = true;
                }
            return prod.Value;
        }
    }

    public static class Huj
    {
        public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> func) where T : class
        {
            T result = null;
            var min = double.MaxValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (min > current)
                {
                    min = current;
                    result = item;
                }
            }
            return result;
        }

        public static T MaxBy<T>(this IEnumerable<T> source, Func<T, double> func, T defaultValue = default(T))
        {
            T result = defaultValue;
            var max = double.MinValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (max < current)
                {
                    max = current;
                    result = item;
                }
            }
            return result;
        }

        public static string JoinStrings(this IEnumerable<string> source, string delimeter)
        {
            return string.Join(delimeter, source.ToArray());
        }

        public static string JoinStrings(this IEnumerable<int> source, string delimeter)
        {
            return source.Select(x => x.ToString()).JoinStrings(delimeter);
        }
    }
}

using System;

namespace _678D
{
    class Program
    {
        static long mod = 1000000007;
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            decimal A = decimal.Parse(input[0]), B = decimal.Parse(input[1]), x = decimal.Parse(input[3]);
            long n = long.Parse(input[2]);
            decimal result = 0;
            if (A == 1)
                result = x + B * n;
            else
            {
                decimal ApowN = BinPow(A, n);
                decimal MulInv = BinPow(A - 1, mod - 2);
                result = ApowN * x + B * ((ApowN - 1) * MulInv) % mod;
            }
            result %= mod;
            Console.WriteLine(result);
        }

        static decimal BinPow(decimal a, long n)
        {
            decimal res = 1;
            while (n > 0)
            {
                if ((n & 1) > 0)
                    res *= a;
                a *= a;
                n >>= 1;
                a %= mod;
                res %= mod;
            }
            return res;
        }
    }
}

#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Globalization;

namespace _13d
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
			Console.SetIn(getInput());
#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
                solution();
            }
            finally
            {
                if (_useFileInput)
                {
                    file.Close();
                }
            }
        }

        static int mod = 1000 * 1000 * 1000 + 7;
        static void mult(long[,] a, long[,] b, long[,] res, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    res[i, j] = 0;
                    for (int k = 0; k < n; k++)
                    {
                        res[i, j] += a[i, k] * b[k, j] % mod;
                        res[i, j] %= mod;
                    }
                }
            }
        }

        static void copy(long[,] from, long[,] to, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int k = 0; k < n; k++)
                {
                    to[i, k] = from[i, k];
                }
            }
        }

        static void pow(long[,] a, long p, int n)
        {
            var temp = new long[n, n];
            var res = new long[n, n];
            for (int i = 0; i < n; i++)
            {
                res[i, i] = 1;
            }

            while (true)
            {
                var rem = p % 2;
                if (rem == 1)
                {
                    mult(res, a, temp, n);
                    copy(temp, res, n);
                }

                if (p == 1)
                {
                    break;
                }

                p /= 2;
                mult(a, a, temp, n);
                copy(temp, a, n);
            }

            copy(res, a, n);
        }

        static void solution()
        {
            #region SOLUTION
            var d = readLongArray();
            var a = d[0];
            var b = d[1];
            var n = d[2];
            var x = d[3];

            var mm = new long[2, 2];
            mm[0, 0] = a;
            mm[0, 1] = b;
            mm[1, 0] = 0;
            mm[1, 1] = 1;

            pow(mm, n, 2);

            var res = x * mm[0, 0] % mod + mm[0, 1];
            Console.WriteLine(res % mod);

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

        static int readInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static long readLong()
        {
            return long.Parse(Console.ReadLine());
        }

        static int[] readIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] readLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
		static StreamReader getInput()
		{
			var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
			var resource = Assembly.GetCallingAssembly().GetManifestResourceStream(resName);

			return new StreamReader(resource);
		}
#endif
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{
    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class IteratedLinearFunctionECR13
    {
        private static int _mod = (int)1e9 + 7;
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                long A = fs.NextLong(), B = fs.NextLong(), n = fs.NextLong(), x = fs.NextLong();
                if (n == 0) writer.WriteLine(x);
                else if (n == 1) writer.WriteLine((A * x + B) % _mod);
                else
                {
                    long[,] initial = new long[,] { { A * x + B, 1 } };
                    long[,] factor = new long[,] { { A, 0 }, { B, 1 } };
                    long[,] res = MultiplyMatricesMod(initial, BinPowMatrixMod(factor, n - 1, _mod), _mod);
                    writer.WriteLine(res[0, 0]);
                }
            }
        }
        public static long BinPow(long a, long p)
        {
            if (p == 0) return 1;
            if ((p & 1) == 0)
            {
                long t = BinPow(a, p / 2);
                return t * t;
            }
            else
            {
                return a * BinPow(a, p - 1);
            }
        }
        public static long BinPowMod(long a, long p, long mod)
        {
            if (p == 0) return 1;
            if ((p & 1) == 0)
            {
                long t = BinPow(a, p / 2);
                return (t * t) % mod;
            }
            else
            {
                return (a % mod * BinPow(a, p - 1)) % mod;
            }
        }

        public static long[,] BinPowMatrix(long[,] a, long p) // p >= 1
        {
            if (a.GetLength(0) != a.GetLength(1))
            {
                throw new Exception("Not a square matrix");
            }

            if (p == 1) return a;
            if ((p & 1) == 0)
            {
                long[,] t = BinPowMatrix(a, p / 2);
                return MultiplyMatrices(t, t);
            }
            else
            {
                return MultiplyMatrices(a, BinPowMatrix(a, p - 1));
            }
        }

        public static long[,] BinPowMatrixMod(long[,] a, long p, long mod) // p >= 1
        {
            if (a.GetLength(0) != a.GetLength(1))
            {
                throw new Exception("Not a square matrix");
            }

            if (p == 1) return a;
            if ((p & 1) == 0)
            {
                long[,] t = BinPowMatrixMod(a, p / 2, mod);
                return MultiplyMatricesMod(t, t, mod);
            }
            else
            {
                return MultiplyMatricesMod(a, BinPowMatrixMod(a, p - 1, mod), mod);
            }
        }

        private static long[,] MultiplyMatrices(long[,] a, long[,] b)
        {
            if (a.GetLength(1) == b.GetLength(0))
            {
                long[,] c = new long[a.GetLength(0), b.GetLength(1)];
                for (int i = 0; i < c.GetLength(0); i++)
                {
                    for (int j = 0; j < c.GetLength(1); j++)
                    {
                        c[i, j] = 0;
                        for (int k = 0; k < a.GetLength(1); k++)
                            c[i, j] = c[i, j] + a[i, k] * b[k, j];
                    }
                }
                return c;
            }
            else
            {
                throw new Exception("Can't multiply because of incompatible sizes");
            }
        }

        private static long[,] MultiplyMatricesMod(long[,] a, long[,] b, long mod)
        {
            if (a.GetLength(1) == b.GetLength(0))
            {
                long[,] c = new long[a.GetLength(0), b.GetLength(1)];
                for (int i = 0; i < c.GetLength(0); i++)
                {
                    for (int j = 0; j < c.GetLength(1); j++)
                    {
                        c[i, j] = 0;
                        for (int k = 0; k < a.GetLength(1); k++)
                        {
                            c[i, j] = c[i, j] + a[i, k] % mod * b[k, j] % mod;
                            c[i, j] %= mod;
                        }
                    }
                }
                return c;
            }
            else
            {
                throw new Exception("Can't multiply because of incompatible sizes");
            }
        }

        private static long[,] MatrixMod(long[,] a, long mod)
        {
            long[,] b = new long[a.GetLength(0), a.GetLength(1)];
            for (int i = 0; i < a.GetLength(0); i++)
            {
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    b[i, j] = a[i, j] % mod;
                }
            }
            return b;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    private const int MOD = 1000000007;

    long ModPow(long x, long p)
    {
        long ret = 1;
        while (p > 0)
        {
            if ((p & 1) == 1)
                ret = ret * x % MOD;
            x = x * x % MOD;
            p >>= 1;
        }
        return ret;
    }

    public void Solve()
    {
        int a = ReadInt();
        int b = ReadInt();
        long n = ReadLong();
        int x = ReadInt();

        if (a == 1)
        {
            Write((x + n % MOD * b) % MOD);
            return;
        }

        long ans = x * ModPow(a, n % (MOD - 1));
        ans += (ModPow(a, n % (MOD - 1)) + MOD - 1) % MOD * ModPow(a - 1, MOD - 2) % MOD * b;
        Write(ans % MOD);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("input.txt");
        //writer = new StreamWriter("output.txt");
#endif
        try
        {
            new Solver().Solve();
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //thread.Start();
            //thread.Join();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Globalization;

class Program
{
    private static long Sqrt3(long x)
    {
        long l = 1;
        long r = Math.Min(1000000, x);
        while (r - l > 1)
        {
            long mid = (l + r) / 2;
            long m3 = mid * mid * mid;
            if (m3 <= x)
                l = mid;
            else
                r = mid;
        }

        return l;
    }

    private static long div(long a, long b)
    {
        return (a * pow(b, Mod - 2, Mod)) % Mod;
    }
    private static long pow(long a, long p, long mod)
    {
        long res = 1;
        while (p > 0)
        {
            if ((p & 1) == 1) res = (res * a) % mod;
            a = (a * a) % mod;
            p >>= 1;
        }
        return res;
    }

    private static long g(long a, long b, long n, long x)
    {
        if (a == 1)
            return (x + b * (n % Mod)) % Mod;

        return ((pow(a, n, Mod) * x) % Mod + (div((pow(a, n, Mod) - 1 + Mod) % Mod, a - 1) * b) % Mod) % Mod;
    }

    private const long Mod = 1000000007;
    static void Main(string[] args)
    {
        Console.Write(g(ReadLong(), ReadLong(), ReadLong(), ReadLong()));
    }

    public class RSQ
    {
        private int[] m = new int[200001];
        public void Push(int pos, int v)
        {
            m[pos] += v;
        }

        public int Sum(int l, int r)
        {
            int ans = 0;
            while (l <= r) ans += m[l++];
            return ans;
        }
    }

    private static List<int>[] ReadGraph(int n, int m)
    {
        List<int>[] g = new List<int>[n + 1];
        for (int i = 0; i <= n; i++) g[i] = new List<int>();
        for (int i = 0; i < m; i++)
        {
            int a = ReadInt() - 1;
            int b = ReadInt() - 1;

            g[a].Add(b);
            g[b].Add(a);
        }

        return g;
    }

    private static int[,] ReadGraphAsMatrix(int n, int m)
    {
        int[,] matrix = new int[n + 1, n + 1];
        for (int i = 0; i < m; i++)
        {
            int a = ReadInt();
            int b = ReadInt();
            matrix[a, b] = matrix[b, a] = 1;
        }

        return matrix;
    }

    private static void Sort(ref int a, ref int b)
    {
        if (a > b) Swap(ref a, ref b);
    }

    private static void Swap(ref int a, ref int b)
    {
        int tmp = a;
        a = b;
        b = tmp;
    }

    private const int BufferSize = 1 << 12;
    private static StreamReader consoleReader;
    private static MemoryStream testData;

    private static int ReadInt()
    {
        int ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static ulong ReadULong()
    {
        ulong ans = 0;
        int chr;
        do
        {
            chr = consoleReader.Read();
            if (chr == -1)
                return 0;
        } while (chr < '0' || chr > '9');

        ans = (uint)(chr - '0');
        while (true)
        {
            chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans;
            ans = ans * 10 + (uint)(chr - '0');
        }
    }

    private static long ReadLong()
    {
        long ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static int[] ReadIntArray(int n)
    {
        int[] ans = new int[n];
        for (int i = 0; i < n; i++)
            ans[i] = ReadInt();
        return ans;
    }

    private static long[] ReadLongArray(int n)
    {
        long[] ans = new long[n];
        for (int i = 0; i < n; i++)
            ans[i] = ReadLong();
        return ans;
    }

    private static char[] ReadString()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        List<char> s = new List<char>();
        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s.ToArray();
    }

    private static char[] ReadString(int n)
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        char[] s = new char[n];
        int pos = 0;
        do
        {
            s[pos++] = (char)ans;
            if (pos == n) break;
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s;
    }

    private static char ReadLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'))
                return (char)ans;
        }
    }

    private static char ReadDigit()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans >= '0' && ans <= '9')
                return (char)ans;
        }
    }

    private static int ReadDigitInt()
    {
        return ReadDigit() - (int)'0';
    }

    private static char ReadAnyChar()
    {
        return (char)consoleReader.Read();
    }

    private static string DoubleToString(double x)
    {
        return x.ToString(System.Globalization.CultureInfo.InvariantCulture);
    }

    static Program()
    {
        //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        consoleReader = new StreamReader(Console.OpenStandardInput(BufferSize), Encoding.ASCII, false, BufferSize);
    }

    private static void PushTestData(string data)
    {
#if !ONLINE_JUDGE
        if (testData == null)
        {
            testData = new MemoryStream();
            consoleReader = new StreamReader(testData);
        }

        var pos = testData.Position;
        var bytes = Encoding.UTF8.GetBytes(data);
        testData.Write(bytes, 0, bytes.Length);
        testData.Flush();
        testData.Position = pos;
#endif
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using Pi = Pair<int, int>;

class Solver
{
    public void Solve(Scanner sc)
    {
        long A, B, n, x;
        sc.Make(out A, out B, out n, out x);
        if (A == 1) Fail((x + (ModInt)B * n));
        ModInt res = ModInt.Pow(A, n)*x;
        res += B * (1 - ModInt.Pow(A, n)) / (1 - A);
        WriteLine(res);
    }
}

public struct ModInt
{
    public const long MOD = (int)1e9 + 7;
    //public const long MOD = 998244353;
    public long Value { get; set; }
    public ModInt(long n = 0) { Value = n; }
    private static ModInt[] fac;//i!
    private static ModInt[] inv;//1/i
    private static ModInt[] facinv;//1/(i!)
    public override string ToString() => Value.ToString();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator +(ModInt l, ModInt r)
    {
        l.Value += r.Value;
        if (l.Value >= MOD) l.Value -= MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator -(ModInt l, ModInt r)
    {
        l.Value -= r.Value;
        if (l.Value < 0) l.Value += MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator *(ModInt l, ModInt r) => new ModInt(l.Value * r.Value % MOD);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator /(ModInt l, ModInt r) => l * Pow(r, MOD - 2);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator long(ModInt l) => l.Value;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator ModInt(long n)
    {
        n %= MOD; if (n < 0) n += MOD;
        return new ModInt(n);
    }

    public static ModInt Pow(ModInt m, long n)
    {
        if (n == 0) return 1;
        if (n % 2 == 0) return Pow(m * m, n >> 1);
        else return Pow(m * m, n >> 1) * m;
    }

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = 1;
        fac[0] = fac[1] = 1;
        facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(ModInt n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(ModInt n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(ModInt n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(ModInt n, ModInt r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        var calc = fac[n];
        calc = calc * facinv[r];
        calc = calc * facinv[n - r];
        return calc;
    }
}
#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static int MaxElement<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    //public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Deconstruct(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion

using System;
using System.Globalization;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace Codeforces
{
    class Program : ProgramBase
    {
        private const long commonMod = 1000000007;

        static void Main(string[] args)
        {
            var p = new Program();
            var x = p.Get();
            p.Out(x);
        }

        object Get()
        {
            checked
            {
                var a = ReadLongToken();
                var b = ReadLongToken();
                var n = ReadLongToken();
                var x = ReadLongToken();
                if (a == 1)
                    return x + b * n;
                var first = (FastPow(a, n, commonMod) * x) % commonMod;
                var q1 = (FastPow(a, n, commonMod) + commonMod - 1);
                var q2 = FastPow(a - 1, commonMod - 2, commonMod);
                var second = b * ((q1 * q2) % commonMod);
                return (first + second) % commonMod;
            }
        }

        long FastPow(long b, long pow, long mod)
        {
            if (pow == 0)
                return 1;
            if (pow == 1)
                return b;
            if (pow % 2 == 0)
                return FastPow((b * b) % mod, pow / 2, mod);
            return (FastPow(b, pow - 1, mod) * b) % mod;
        }

        //object Get()
        //{
        //    checked
        //    {
        //        var n = ReadIntToken();
        //        var k = ReadIntToken();
        //        var table = new bool[n, n];
        //        for (int i = 0; i < n; i++)
        //        {
        //            var input = Read();
        //            for (int j = 0; j < n; j++)
        //                table[i, j] = input[j] == '.';
        //        }
        //        var cells = BFS(table);
        //    }
        //}
        //Cell[,] BFS(bool[,] input)
        //{
        //    var n = input.GetLength(0);
        //    var cells = new Cell[n, n];
        //    var visited = new bool[n, n];
        //    var componentIndex = 0;
        //    for (int i = 0; i < n; i++)
        //    {
        //        for (int j = 0; j < n; j++)
        //        {
        //            if (!visited[i, j] && input[i, j])
        //                BFS(i, j, cells, input, visited, componentIndex);
        //        }
        //    }
        //}

        //void BFS(int i, int j, Cell[,] cells, bool[,] input, bool[,] visited, int ccIndex)
        //{
        //    var n = input.GetLength(0);
        //    for
        //}

        struct Cell
        {
            int CCNumber { get; set; }
        }

        class Automata
        {
            bool[] terminals;
            public int sigma;
            public int len;
            public int[,] jumps;

            public void Create()
            {
                var a = ReadInts();
                len = a[0];
                sigma = a[2];
                var ts = ReadInts();
                terminals = new bool[len];
                for (int i = 0; i < ts.Length; i++)
                    terminals[ts[i]] = true;
                jumps = new int[len, sigma];
                for (int i = 0; i < len * sigma; i++)
                {
                    var b = Console.ReadLine().Split(' ');
                    jumps[Convert.ToInt32(b[0]), b[1][0] - 'a'] = Convert.ToInt32(b[2]);
                }
            }
            protected int[] ReadInts()
            {
                return Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToArray();
            }

            public bool IsTerminal(int s)
            {
                return terminals[s];
            }
        }
    }

    abstract class ProgramBase
    {
        bool? prod = null;
        StreamReader f;
        Queue<string> tokens;
        protected string FileName { private get; set; }

        protected string Read()
        {
            if (f == null)
                f = string.IsNullOrEmpty(FileName)
                    ? new StreamReader(Console.OpenStandardInput())
                    : new StreamReader((GetProd() ? "" : "c:\\dev\\") + FileName);
            return f.ReadLine();
        }

        protected int ReadInt()
        {
            return int.Parse(Read());
        }

        protected int ReadIntToken()
        {
            if (tokens == null || tokens.Count == 0)
                tokens = new Queue<string>(Read().Split(' '));
            return int.Parse(tokens.Dequeue());
        }

        protected int[] ReadInts()
        {
            var tokens = Read().Split(' ');
            var result = new int[tokens.Length];
            for (int i = 0; i < tokens.Length; i++)
                result[i] = int.Parse(tokens[i]);
            return result;
        }

        protected long ReadLongToken()
        {
            if (tokens == null || tokens.Count == 0)
                tokens = new Queue<string>(Read().Split(' '));
            return long.Parse(tokens.Dequeue());
        }

        protected long ReadLong()
        {
            return Convert.ToInt64(Read());
        }

        protected long[] ReadLongs()
        {
            var tokens = Read().Split(' ');
            var result = new long[tokens.Length];
            for (int i = 0; i < tokens.Length; i++)
                result[i] = long.Parse(tokens[i]);
            return result;
        }

        public void Out(object r)
        {
            if (string.IsNullOrEmpty(FileName))
                Console.WriteLine(r);
            else if (GetProd())
                File.WriteAllText(FileName, r.ToString());
            else
                Console.WriteLine(r);
        }

        private bool GetProd()
        {

            if (!prod.HasValue)
                try
                {
                    prod = Environment.MachineName != "RENADEEN-W7";
                }
                catch (Exception)
                {
                    prod = true;
                }
            return prod.Value;
        }
    }

    public static class Huj
    {
        public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> func) where T : class
        {
            T result = null;
            var min = double.MaxValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (min > current)
                {
                    min = current;
                    result = item;
                }
            }
            return result;
        }

        public static T MaxBy<T>(this IEnumerable<T> source, Func<T, double> func, T defaultValue = default(T))
        {
            T result = defaultValue;
            var max = double.MinValue;
            foreach (var item in source)
            {
                var current = func(item);
                if (max < current)
                {
                    max = current;
                    result = item;
                }
            }
            return result;
        }

        public static string JoinStrings(this IEnumerable<string> source, string delimeter)
        {
            return string.Join(delimeter, source.ToArray());
        }

        public static string JoinStrings(this IEnumerable<int> source, string delimeter)
        {
            return source.Select(x => x.ToString()).JoinStrings(delimeter);
        }
    }
}

#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Globalization;

namespace _13d
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
			Console.SetIn(getInput());
#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
                solution();
            }
            finally
            {
                if (_useFileInput)
                {
                    file.Close();
                }
            }
        }

        static int mod = 1000 * 1000 * 1000 + 7;
        static void mult(long[,] a, long[,] b, long[,] res, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    res[i, j] = 0;
                    for (int k = 0; k < n; k++)
                    {
                        res[i, j] += a[i, k] * b[k, j];// % mod;
                        //res[i, j] %= mod;
                    }
                }
            }
        }

        static void copy(long[,] from, long[,] to, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int k = 0; k < n; k++)
                {
                    to[i, k] = from[i, k];
                }
            }
        }

        static void pow(long[,] a, long p, int n)
        {
            var temp = new long[n, n];
            var res = new long[n, n];
            for (int i = 0; i < n; i++)
            {
                res[i, i] = 1;
            }

            while (true)
            {
                var rem = p % 2;
                if (rem == 1)
                {
                    mult(res, a, temp, n);
                    copy(temp, res, n);
                }

                if (p == 1)
                {
                    break;
                }

                p /= 2;
                mult(a, a, temp, n);
                copy(temp, a, n);
            }

            copy(res, a, n);
        }

        static void solution()
        {
            #region SOLUTION
            var d = readLongArray();
            var a = d[0];
            var b = d[1];
            var n = d[2];
            var x = d[3];

            var mm = new long[2, 2];
            mm[0, 0] = a;
            mm[0, 1] = b;
            mm[1, 0] = 0;
            mm[1, 1] = 1;

            pow(mm, n, 2);

            var res = x * mm[0, 0] % mod + mm[0, 1];
            Console.WriteLine(res);

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

        static int readInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static long readLong()
        {
            return long.Parse(Console.ReadLine());
        }

        static int[] readIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] readLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
		static StreamReader getInput()
		{
			var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
			var resource = Assembly.GetCallingAssembly().GetManifestResourceStream(resName);

			return new StreamReader(resource);
		}
#endif
    }
}

#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Globalization;

namespace _13d
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
			Console.SetIn(getInput());
#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
                solution();
            }
            finally
            {
                if (_useFileInput)
                {
                    file.Close();
                }
            }
        }

        static int mod = 1000 * 1000 * 1000 + 7;
        static void mult(long[,] a, long[,] b, long[,] res, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    res[i, j] = 0;
                    for (int k = 0; k < n; k++)
                    {
                        res[i, j] += a[i, k] * b[k, j] % mod;
                        res[i, j] %= mod;
                    }
                }
            }
        }

        static void copy(long[,] from, long[,] to, int n)
        {
            for (int i = 0; i < n; i++)
            {
                for (int k = 0; k < n; k++)
                {
                    to[i, k] = from[i, k];
                }
            }
        }

        static void pow(long[,] a, long p, int n)
        {
            var temp = new long[n, n];
            var res = new long[n, n];
            for (int i = 0; i < n; i++)
            {
                res[i, i] = 1;
            }

            while (true)
            {
                var rem = p % 2;
                if (rem == 1)
                {
                    mult(res, a, temp, n);
                    copy(temp, res, n);
                }

                if (p == 1)
                {
                    break;
                }

                p /= 2;
                mult(a, a, temp, n);
                copy(temp, a, n);
            }

            copy(res, a, n);
        }

        static void solution()
        {
            #region SOLUTION
            var d = readLongArray();
            var a = d[0];
            var b = d[1];
            var n = d[2];
            var x = d[3];

            var mm = new long[2, 2];
            mm[0, 0] = a;
            mm[0, 1] = b;
            mm[1, 0] = 0;
            mm[1, 1] = 1;

            pow(mm, n, 2);

            var res = x * mm[0, 0] % mod + mm[0, 1];
            Console.WriteLine(res);

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

        static int readInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static long readLong()
        {
            return long.Parse(Console.ReadLine());
        }

        static int[] readIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] readLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
		static StreamReader getInput()
		{
			var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
			var resource = Assembly.GetCallingAssembly().GetManifestResourceStream(resName);

			return new StreamReader(resource);
		}
#endif
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgoTraining.Codeforces.D_s
{
    public class FastScanner : StreamReader
    {
        private string[] _line;
        private int _iterator;

        public FastScanner(Stream stream) : base(stream)
        {
            _line = null;
            _iterator = 0;
        }
        public int NextInt()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt32(_line[_iterator++]);
        }
        public long NextLong()
        {
            if (_line == null || _iterator >= _line.Length)
            {
                _line = base.ReadLine().Split(' ');
                _iterator = 0;
            }
            if (_line.Count() == 0) throw new IndexOutOfRangeException("Input string is empty");
            return Convert.ToInt64(_line[_iterator++]);
        }
    }
    class IteratedLinearFunctionECR13
    {
        private static int _mod = (int)1e9 + 7;
        public static void Main(string[] args)
        {
            using (FastScanner fs = new FastScanner(new BufferedStream(Console.OpenStandardInput())))
            using (StreamWriter writer = new StreamWriter(new BufferedStream(Console.OpenStandardOutput())))
            {
                long A = fs.NextLong(), B = fs.NextLong(), n = fs.NextLong(), x = fs.NextLong();
                if (n == 0) writer.WriteLine(x);
                else if (n == 1) writer.WriteLine(A * x + B);
                else
                {
                    long[,] initial = new long[,] { { A * x + B, 1 } };
                    long[,] factor = new long[,] { { A, 0 }, { B, 1 } };
                    long[,] res = MultiplyMatricesMod(initial, BinPowMatrixMod(factor, n - 1, _mod), _mod);
                    writer.WriteLine(res[0, 0]);
                }
            }
        }
        public static long BinPow(long a, long p)
        {
            if (p == 0) return 1;
            if ((p & 1) == 0)
            {
                long t = BinPow(a, p / 2);
                return t * t;
            }
            else
            {
                return a * BinPow(a, p - 1);
            }
        }
        public static long BinPowMod(long a, long p, long mod)
        {
            if (p == 0) return 1;
            if ((p & 1) == 0)
            {
                long t = BinPow(a, p / 2);
                return (t * t) % mod;
            }
            else
            {
                return (a % mod * BinPow(a, p - 1)) % mod;
            }
        }

        public static long[,] BinPowMatrix(long[,] a, long p) // p >= 1
        {
            if (a.GetLength(0) != a.GetLength(1))
            {
                throw new Exception("Not a square matrix");
            }

            if (p == 1) return a;
            if ((p & 1) == 0)
            {
                long[,] t = BinPowMatrix(a, p / 2);
                return MultiplyMatrices(t, t);
            }
            else
            {
                return MultiplyMatrices(a, BinPowMatrix(a, p - 1));
            }
        }

        public static long[,] BinPowMatrixMod(long[,] a, long p, long mod) // p >= 1
        {
            if (a.GetLength(0) != a.GetLength(1))
            {
                throw new Exception("Not a square matrix");
            }

            if (p == 1) return a;
            if ((p & 1) == 0)
            {
                long[,] t = BinPowMatrixMod(a, p / 2, mod);
                return MultiplyMatricesMod(t, t, mod);
            }
            else
            {
                return MultiplyMatricesMod(a, BinPowMatrixMod(a, p - 1, mod), mod);
            }
        }

        private static long[,] MultiplyMatrices(long[,] a, long[,] b)
        {
            if (a.GetLength(1) == b.GetLength(0))
            {
                long[,] c = new long[a.GetLength(0), b.GetLength(1)];
                for (int i = 0; i < c.GetLength(0); i++)
                {
                    for (int j = 0; j < c.GetLength(1); j++)
                    {
                        c[i, j] = 0;
                        for (int k = 0; k < a.GetLength(1); k++)
                            c[i, j] = c[i, j] + a[i, k] * b[k, j];
                    }
                }
                return c;
            }
            else
            {
                throw new Exception("Can't multiply because of incompatible sizes");
            }
        }

        private static long[,] MultiplyMatricesMod(long[,] a, long[,] b, long mod)
        {
            if (a.GetLength(1) == b.GetLength(0))
            {
                long[,] c = new long[a.GetLength(0), b.GetLength(1)];
                for (int i = 0; i < c.GetLength(0); i++)
                {
                    for (int j = 0; j < c.GetLength(1); j++)
                    {
                        c[i, j] = 0;
                        for (int k = 0; k < a.GetLength(1); k++)
                        {
                            c[i, j] = c[i, j] + a[i, k] % mod * b[k, j] % mod;
                            c[i, j] %= mod;
                        }
                    }
                }
                return c;
            }
            else
            {
                throw new Exception("Can't multiply because of incompatible sizes");
            }
        }

        private static long[,] MatrixMod(long[,] a, long mod)
        {
            long[,] b = new long[a.GetLength(0), a.GetLength(1)];
            for (int i = 0; i < a.GetLength(0); i++)
            {
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    b[i, j] = a[i, j] % mod;
                }
            }
            return b;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    private const int MOD = 1000000007;

    long ModPow(long x, long p)
    {
        long ret = 1;
        while (p > 0)
        {
            if ((p & 1) == 1)
                ret = ret * x % MOD;
            x = x * x % MOD;
            p >>= 1;
        }
        return ret;
    }

    public void Solve()
    {
        int a = ReadInt();
        int b = ReadInt();
        long n = ReadLong();
        int x = ReadInt();

        if (a == 1)
        {
            Write((x + 1L * n * b) % MOD);
            return;
        }

        long ans = x * ModPow(a, n % (MOD - 1));
        ans += (ModPow(a, n % (MOD - 1)) + MOD - 1) % MOD * ModPow(a - 1, MOD - 2) % MOD * b;
        Write(ans % MOD);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("input.txt");
        //writer = new StreamWriter("output.txt");
#endif
        try
        {
            new Solver().Solve();
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //thread.Start();
            //thread.Join();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
#if DEBUG
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using Pi = Pair<int, int>;

class Solver
{
    public void Solve(Scanner sc)
    {
        long A, B, n, x;
        sc.Make(out A, out B, out n, out x);
        ModInt res = ModInt.Pow(A, n);
        res += B * (1 - ModInt.Pow(A, n)) / (1 - A);
        WriteLine(res);
    }
}

public struct ModInt
{
    public const long MOD = (int)1e9 + 7;
    //public const long MOD = 998244353;
    public long Value { get; set; }
    public ModInt(long n = 0) { Value = n; }
    private static ModInt[] fac;//i!
    private static ModInt[] inv;//1/i
    private static ModInt[] facinv;//1/(i!)
    public override string ToString() => Value.ToString();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator +(ModInt l, ModInt r)
    {
        l.Value += r.Value;
        if (l.Value >= MOD) l.Value -= MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator -(ModInt l, ModInt r)
    {
        l.Value -= r.Value;
        if (l.Value < 0) l.Value += MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator *(ModInt l, ModInt r) => new ModInt(l.Value * r.Value % MOD);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator /(ModInt l, ModInt r) => l * Pow(r, MOD - 2);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator long(ModInt l) => l.Value;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator ModInt(long n)
    {
        n %= MOD; if (n < 0) n += MOD;
        return new ModInt(n);
    }

    public static ModInt Pow(ModInt m, long n)
    {
        if (n == 0) return 1;
        if (n % 2 == 0) return Pow(m * m, n >> 1);
        else return Pow(m * m, n >> 1) * m;
    }

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = 1;
        fac[0] = fac[1] = 1;
        facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(ModInt n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(ModInt n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(ModInt n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(ModInt n, ModInt r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        var calc = fac[n];
        calc = calc * facinv[r];
        calc = calc * facinv[n - r];
        return calc;
    }
}
#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static int MaxElement<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    //public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Deconstruct(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using Pi = Pair<int, int>;

class Solver
{
    public void Solve(Scanner sc)
    {
        long A, B, n, x;
        sc.Make(out A, out B, out n, out x);
        ModInt res = ModInt.Pow(A, n)*x;
        res += B * (1 - ModInt.Pow(A, n)) / (1 - A);
        WriteLine(res);
    }
}

public struct ModInt
{
    public const long MOD = (int)1e9 + 7;
    //public const long MOD = 998244353;
    public long Value { get; set; }
    public ModInt(long n = 0) { Value = n; }
    private static ModInt[] fac;//i!
    private static ModInt[] inv;//1/i
    private static ModInt[] facinv;//1/(i!)
    public override string ToString() => Value.ToString();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator +(ModInt l, ModInt r)
    {
        l.Value += r.Value;
        if (l.Value >= MOD) l.Value -= MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator -(ModInt l, ModInt r)
    {
        l.Value -= r.Value;
        if (l.Value < 0) l.Value += MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator *(ModInt l, ModInt r) => new ModInt(l.Value * r.Value % MOD);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator /(ModInt l, ModInt r) => l * Pow(r, MOD - 2);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator long(ModInt l) => l.Value;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator ModInt(long n)
    {
        n %= MOD; if (n < 0) n += MOD;
        return new ModInt(n);
    }

    public static ModInt Pow(ModInt m, long n)
    {
        if (n == 0) return 1;
        if (n % 2 == 0) return Pow(m * m, n >> 1);
        else return Pow(m * m, n >> 1) * m;
    }

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = 1;
        fac[0] = fac[1] = 1;
        facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(ModInt n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(ModInt n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(ModInt n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(ModInt n, ModInt r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        var calc = fac[n];
        calc = calc * facinv[r];
        calc = calc * facinv[n - r];
        return calc;
    }
}
#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static int MaxElement<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    //public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Deconstruct(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion