long[][] initMatrix(int n, int start) { long[][] m = Matrix.unit(n); for (int i = 0; i < start; i++) { m[i][start] = 1; } return m; }
public int solve(long coins_sum, long[] values) { int n = values.length; long[][][] step = new long[n][][]; step[0] = Matrix.unit(n); for (int i = 1; i < n; i++) { long div = values[i] / values[i - 1]; step[i] = Matrix.mul(initMatrix(n, i), Matrix.pow(step[i - 1], div, MOD), MOD); } long[][] total = Matrix.unit(n); for (int i = n - 1; i >= 0; i--) { long length = coins_sum / values[i]; coins_sum %= values[i]; total = Matrix.mul(Matrix.pow(step[i], length, MOD), total, MOD); } long res = 0; for (int i = 0; i < n; i++) { res += total[0][i]; } return (int) (res % MOD); }