Problem:
Compressed Formula
You are given a simple, but long formula in a compressed format. A compressed formula is a sequence of $N$ pairs of an integer $r_i$ and a string $s_i$, which consists only of digits ('0'-'9'), '+', '-', and '*'. To restore the original formula from a compressed formula, first we generate strings obtained by repeating $s_i$ $r_i$ times for all $i$, then we concatenate them in order of the sequence.
You can assume that a restored original formula is well-formed. More precisely, a restored formula satisfies the following BNF:
<expression> := <term> | <expression> '+' <term> | <expression> '-' <term>
<term> := <number> | <term> * <number>
<number> := <digit> | <non-zero-digit> <number>
<digit> := '0' | <non-zero-digit>
<non-zero-digit> := '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
Here, '+' means addition, '-' means subtraction, and '*' means multiplication of integers.
Your task is to write a program computing the answer of a given formula modulo 1,000,000,007, where $x$ modulo $m$ is a non-negative integer $r$ such that there exists an integer $k$ satisfying $x = km + r$ and $0 \leq r < m$; it is guaranteed that such $r$ is uniquely determined for integers $x$ and $m$.
Input
The input consists of a single test case.
$N$
$r_1$ $s_1$
$r_2$ $s_2$
...
$r_N$ $s_N$
The first line contains a single integer $N$ ($1 \leq N \leq 10^4$), which is the length of a sequence of a compressed formula. The following $N$ lines represents pieces of a compressed formula. The $i$-th line consists of an integer $r_i$ ($1 \leq r_i \leq 10^9$) and a string $s_i$ ($1 \leq |s_i| \leq 10$), where $t_i$ is the number of repetition of $s_i$, and $s_i$ is a piece of an original formula. You can assume that an original formula, restored from a given compressed formula by concatenation of repetition of pieces, satisfies the BNF in the problem statement.
Output
Print the answer of a given compressed formula modulo 1,000,000,007.
Sample Input 1
1
5 1
Output for the Sample Input 1
11111
Sample Input 2
2
19 2*
1 2
Output for the Sample Input 2
1048576
Sample Input 3
2
1 1-10
10 01*2+1
Output for the Sample Input 3
999999825
Sample Input 4
4
3 12+45-12
4 12-3*2*1
5 12345678
3 11*23*45
Output for the Sample Input 4
20008570

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for(ll i=0; i <ll(n); i++)
template <class T> using V = vector<T>;
template <class A, class B>
bool chmax(A &a, B b) { return a < b && (a=b, true); }
template <class A, class B>
bool chmin(A &a, B b) { return b < a && (a=b, true); }

template <int MD, int g = 3>
struct ModInt {
  using M = ModInt;
  const static inline M G = g;
  unsigned int v;
  ModInt() : v(0) {}
  ModInt(ll w) : v(w % MD + MD) {
    if(v >= MD) v -= MD;
  }
  static M raw(unsigned int v) {
    M res;
    res.v = (v < MD) ? v : v - MD;
    return res;
  }
  explicit operator bool() const {
    return v != 0;
  }
  M operator-() const {
    return M() - *this;
  }
  M operator+(M r) const {
    return raw(v + r.v);
  }
  M operator-(M r) const {
    return raw(v + MD - r.v);
  }
  M operator*(M r) const {
    return raw(ll(v) * r.v % MD);
  }
  M operator/(M r) const {
    return *this * r.inv();
  }
  M& operator+=(M r) {
    return *this = *this + r;
  }
  M& operator-=(M r) {
    return *this = *this - r;
  }
  M& operator*=(M r) {
    return *this = *this * r;
  }
  M& operator/=(M r) {
    return *this = *this / r;
  }
  bool operator==(M r) const {
    return v == r.v;
  }
  M pow(ll n) const {
    M x = *this, r = 1;
    while (n) {
      if (n & 1) r *= x;
      x *= x;
      n >>= 1;
    }
    return r;
  }
  M inv() const {
    return pow(MD - 2);
  }
  friend ostream& operator<<(ostream& os, M r) {
    return os << r.v;
  }
};
using Mint = ModInt<1000000007>;

const int Z = 4;
using Node = array<array<Mint, Z>, Z>;
Node mul(Node l, Node r){
  Node res;
  REP(i,Z) REP(j,Z) REP(k,Z) res[i][k] += l[i][j] * r[j][k];
  return res;
}
Node pow(Node a, ll i){
  if(i == 0){
    Node res;
    REP(i,Z) res[i][i] = 1;
    return res;
  }
  auto b = pow(mul(a,a), i/2);
  if(i%2 == 1) b = mul(b, a);
  return b;
}

void testcase(){
  ll N; cin >> N;
  Node res;
  res[0][3] = 1;
  res[0][0] = 1;
  REP(i,N){
    ll t; cin >> t;
    string s; cin >> s;
    Node x = pow(Node(), 0);
    for(auto c : s){
      Node y;
      if('0' <= c && c <= '9'){
        y[0][0] = 1;
        y[0][1] = c - '0';
        y[1][1] = 10;
        y[2][2] = 1;
        y[3][3] = 1;
      } else if(c == '*'){
        y[1][0] = 1;
        y[2][2] = 1;
        y[3][3] = 1;
      } else if(c == '+' || c == '-') {
        Mint co = (c == '-' ? -1 : 1);
        y[3][0] = co;
        y[1][2] = 1;
        y[2][2] = 1;
        y[3][3] = 1;
      }
      x = mul(x, y);
    }
    res = mul(res, pow(x, t));
  }
  Mint ans = res[0][1] + res[0][2];
  cout << ans.v << "\n";
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  testcase();
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3444
final_rank: 8

code_snippet: #include <bits/stdtr1c++.h>

#define MOD 1000000007
#define clr(ar) memset(ar, 0, sizeof(ar))

using namespace std;

struct Matrix{
    int row, col, ar[5][5];

    Matrix(){}
    Matrix(int n, int m, int diagonal = 0){
        clr(ar);
        row = n, col = m;
        for (int i = min(n, m) - 1; i >= 0; i--) ar[i][i] = diagonal;
    }

    Matrix operator* (const Matrix& other) const{
        int i, j, k;
		Matrix res(row, other.col);

		for(i = 0; i < row; i++){
			for(j = 0; j < other.col; j++){
                long long x = 0;
				for(k = 0; k < col; k++){
					x += ((long long)ar[i][k] * other.ar[k][j]);
				}
				res.ar[i][j] = x % MOD;
			}
		}
		return res;
	}

	Matrix operator^ (long long n) const{
	    Matrix x = *this, res = Matrix(row, col, 1);
		while (n){
			if (n & 1) res = res * x;
			n = n >> 1, x = x * x;
		}
		return res;
	}
} add, sub, mul, res;

const int n = 4;
char str[10010];

void generate(){
    add = Matrix(n, n, 1);
    for (int i = 0; i < 2; i++){
        swap(add.ar[i + 1][i + 1], add.ar[i][i + 2]);
    }

    sub = add;
    sub.ar[1][3] = MOD - 1;

    mul = sub;
    mul.ar[1][3] = 0;
    swap(mul.ar[0][2], mul.ar[1][2]);

    res = Matrix(n, n);
    res.ar[1][0] = res.ar[3][0] = 1;
}

void run(int k, const char* str){
    int i, j;
    Matrix x = Matrix(n, n, 1);

    for (i = 0; str[i]; i++){
        if (str[i] == '+') x = add * x;
        else if (str[i] == '-') x = sub * x;
        else if (str[i] == '*') x = mul * x;
        else{
            Matrix y = Matrix(n, n, 1);
            y.ar[2][1] = str[i] - 48, y.ar[2][2] *= 10;
            x = y * x;
        }
    }

    x = x ^ k;
    res = x * res;
}

int main(){
    generate();
    int q, i, j, k, l, x, y, z;

    scanf("%d", &q);
    while (q--){
        scanf("%d %s", &k, str);
        run(k, str);
    }

    res = add * res;
    printf("%d\n", res.ar[0][0]);
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3588
final_rank: 5

code_snippet: #include <bits/stdc++.h>
// 04:00

constexpr long long mod = 1000000007;

long long mod_pow(long long base, long long exp) {
    long long res = 1;
    while (exp > 0) {
        if (exp & 1) {
            res *= base;
            res %= mod;
        }
        base *= base;
        base %= mod;
        exp >>= 1;
    }
    return res;
}

// sum (k ^ i) (0 <= i < n)
long long sum_mul(long long k, long long n) {
    if (k == 0) return 0;
    if (k == 1) return n;
    long long res = (mod_pow(k, n) - 1 + mod) % mod;
    res *= mod_pow(k - 1, mod - 2);
    res %= mod;
    return res;
}

struct SimpleParser {
    using CopyIter = std::string::const_iterator;
    using Iter = CopyIter&;
    std::string line;

    SimpleParser(std::string s): line(s) {}

    void skip(Iter it, char c) {
        assert(*it == c);
        ++it;
    }

    long long parse() {
        // std::cerr << "start" << std::endl;
        auto it = line.cbegin();
        auto res = expr(it);
        // std::cerr << "finish" << std::endl;
        return res;
    }

    long long expr(Iter it) {
        auto res = term(it);
        while (it != line.end() && (*it == '+' || *it == '-')) {
            auto op = *it;
            if (op == '+') {
                skip(it, '+');
                res = (res + term(it)) % mod;
            } else {
                skip(it, '-');
                res = (res - term(it) + mod) % mod;
            }
        }
        return res;
    }

    long long term(Iter it) {
        auto res = factor(it);
        while (it != line.end() && (*it == '*')) {
            skip(it, '*');
            res = res * factor(it) % mod;
        }
        return res;
    }

    long long factor(Iter it) {
        bool minus = false;
        if (*it == '+') {
            skip(it, '+');
        } else if (*it == '-') {
            skip(it, '-');
            minus = true;
        }
        auto res = number(it);
        if (minus) {
            res = (2 * mod - res) % mod;
        }
        return res;
    }

    long long number(Iter it) {
        long long res = 0;
        while (it != line.end() && std::isdigit(*it)) {
            char c = *it;
            skip(it, c);
            res = 10 * res + c - '0';
            res %= mod;
        }
        return res;
    }
};

// + - *
std::pair<long long, std::string> to_A(const std::pair<long long, std::string>& line) {
    auto [r, s] = line;
    size_t pos = 0;

    if (s.find('+') != std::string::npos) {
        pos = std::max(pos, s.find_last_of('+'));
    }
    if (s.find('-') != std::string::npos) {
        pos = std::max(pos, s.find_last_of('-'));
    }

    std::string lhs = s.substr(0, pos);
    std::string rhs = s.substr(pos);
    assert(rhs.front() == '+' || rhs.front() == '-');
    SimpleParser parser(rhs + lhs);
    auto val = parser.parse();
    val = (r - 1) * val % mod;

    std::string res = (lhs + '+' + std::to_string(val) + rhs);
    return {1, res};
}

// *
std::pair<long long, std::string> to_B(const std::pair<long long, std::string>& line) {
    auto [r, s] = line;
    assert(s.find('*') != std::string::npos);
    size_t pos = s.find('*');

    std::string lhs = s.substr(0, pos);
    std::string rhs = s.substr(pos);
    assert(rhs.front() == '*');

    std::string temp = rhs + lhs;
    temp.erase(temp.begin());
    SimpleParser parser(temp);
    auto val = parser.parse();
    val = mod_pow(val, r - 1);
    std::string res = (lhs + "*" + std::to_string(val) + rhs);
    return {1, res};
}

// + -
std::pair<long long, std::string> to_C(const std::pair<long long, std::string>& line) {
    auto [r, s] = line;
    size_t pos = 0;

    if (s.find('+') != std::string::npos) {
        pos = std::max(pos, s.find_last_of('+'));
    }
    if (s.find('-') != std::string::npos) {
        pos = std::max(pos, s.find_last_of('-'));
    }

    std::string lhs = s.substr(0, pos);
    std::string rhs = s.substr(pos);
    assert(rhs.front() == '+' || rhs.front() == '-');
    SimpleParser parser(rhs + lhs);
    auto val = parser.parse();
    val = (r - 1) * val % mod;

    std::string res = (lhs + '+' + std::to_string(val) + rhs);
    return {1, res};
}

std::pair<long long, std::string> to_D(const std::pair<long long, std::string>& line) {
    return line;
}

std::pair<long long, std::string> preprocess(const std::pair<long long, std::string>& line) {
    auto [r, s] = line;
    bool has_plus_or_minus = (s.find('+') != std::string::npos) || (s.find('-') != std::string::npos);
    bool has_mul = (s.find('*') != std::string::npos);

    if (has_plus_or_minus && has_mul) {
        return to_A(line);
    } else if (has_mul) {
        return to_B(line);
    } else if (has_plus_or_minus) {
        return to_C(line);
    } else {
        return to_D(line);
    }
}

std::string concat(const std::vector<std::pair<long long, std::string>>& formulas) {
    // std::cerr << "start concat" << std::endl;
    std::string res;
    long long val = 0;
    for (int i = 0; i < (int)formulas.size(); i++) {
        // std::cerr << "concat roop " << i << std::endl;
        auto [r, s] = formulas[i];
        if (r != 1) {
            // std::cerr << "ASDASDASDASD" << std::endl;
            assert(std::all_of(s.begin(), s.end(), [](char c) { return std::isdigit(c); }));
            val *= mod_pow(10, s.size() * r);
            val %= mod;

            long long k = mod_pow(10, s.size());
            SimpleParser parser(s);
            auto s_val = parser.parse();
            val += s_val * sum_mul(k, r) % mod;
            val %= mod;
        } else {
            // std::cerr << "ASDASD" << std::endl;
            for (int j = 0; j < (int)s.size(); j++) {
                if (std::isdigit(s[j])) {
                    val = (10 * val + s[j] - '0') % mod;
                } else {
                    res += std::to_string(val);
                    val = 0;
                    res.push_back(s[j]);
                }
            }
        }

        if (i + 1 == (int)formulas.size()) {
            res += std::to_string(val);
            val = 0;
        }
    }
    // std::cerr << "end concat" << std::endl;
    return res; 
}

int main() {
    int n;
    std::cin >> n;
    std::vector<std::pair<long long, std::string>> formulas;
    for (int i = 0; i < n; i++) {
        long long r;
        std::string s;
        std::cin >> r >> s;
        formulas.push_back(preprocess({r, s}));
    }

    // std::cerr << "------------ " << std::endl;
    // std::cerr << "after preprocess " << std::endl;
    // for (auto [r, s]: formulas) {
    //     std::cerr << r << ' ' << s << std::endl;
    // }
    std::string line = concat(formulas);
    // std::cerr << "------------ " << std::endl;
    // std::cerr << "after concat " << std::endl;
    // std::cerr << line << std::endl;

    SimpleParser parser(line);
    std::cout << parser.parse() << std::endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4444
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 最初 * がないと思って誤読した．痛すぎる．
const long long mod = 1000000007;

long long modpow(long long a, long long b, long long m) {
    long long p = 1, q = a;
    for (int i = 0; i < 60; i++) {
        if ((b >> i) & 1) { p *= q; p %= m; }
        q *= q; q %= m;
    }
    return p;
}

long long Division(long long a, long long b, long long m) {
    return (a * modpow(b, m - 2, m)) % m;
}

// ================================================ Solve Function ================================================
long long StoiMod(string str) {
    long long eval = 0;
    for (int i = 0; i < (int)str.size(); i++) {
        eval *= 10LL;
        eval += (long long)(str[i] - '0');
        eval %= mod;
    }
    return eval;
}

long long Repeat(string str, long long rep) {
    long long val1 = modpow(10, (long long)str.size(), mod);
    long long val2 = modpow(val1, rep, mod);
    long long val3 = Division((val2 + mod - 1) % mod, (val1 + mod - 1) % mod, mod);
    long long base = StoiMod(str);
    return val3 * base % mod;
}

long long Solve(vector<pair<string, long long>> Vec) {
    long long Answer1 = 1;
    long long Answer2 = 1;
    vector<vector<string>> List(Vec.size(), vector<string>{});
    /*cout << "Solve:" << endl;
    for (int i = 0; i < Vec.size(); i++) cout << " - " << Vec[i].first << " " << Vec[i].second << endl;*/

    // Decompression
    for (int i = 0; i < (int)Vec.size(); i++) {
        string str = "";
        for (int j = 0; j < (int)Vec[i].first.size(); j++) {
            if (Vec[i].first[j] == '*') {
                List[i].push_back(str);
                str = "";
            }
            else str += Vec[i].first[j];
        }
        List[i].push_back(str);
    }

    // Pattern 1
    for (int i = 0; i < (int)Vec.size(); i++) {
        if (List[i].size() == 1) continue;
        for (int j = 1; j < (int)List[i].size() - 1; j++) {
            long long val = StoiMod(List[i][j]);
            Answer1 *= modpow(val, Vec[i].second, mod);
            Answer1 %= mod;
        }
        string str = "";
        str += List[i][List[i].size() - 1];
        str += List[i][0];
        long long val = StoiMod(str);
        Answer1 *= modpow(val, Vec[i].second - 1, mod);
        Answer1 %= mod;
    }

    // Pattern 2
    int cx = 0;
    while (cx < (int)Vec.size()) {
        int Fin = cx;
        bool Flag = false;
        long long Current = 0;
        if (List[cx].size() == 1) Current = Repeat(List[cx][List[cx].size() - 1], Vec[cx].second);
        if (List[cx].size() >= 2) Current = Repeat(List[cx][List[cx].size() - 1], 1);

        // Going Forward
        for (int i = cx + 1; i < (int)Vec.size(); i++) {
            long long Len = List[i][0].size();
            long long Tim = Vec[i].second; if (List[i].size() >= 2) Tim = 1;
            Current *= modpow(10LL, Len * Tim, mod);
            Current %= mod;
            Fin = i;
            Current += Repeat(List[i][0], Tim);
            Current %= mod;
            if (List[i].size() >= 2) break;
            if (i == (int)Vec.size() - 1) Flag = true;
        }

        // Terminal
        Answer2 *= Current;
        Answer2 %= mod;
        if (Flag == true || cx == (int)Vec.size() - 1) break;
        cx = Fin;
    }
    if (List[0].size() >= 2) {
        Answer2 *= Repeat(List[0][0], 1);
        Answer2 %= mod;
    }

    // Return
    /*cout << " - Return = " << Answer1 * Answer2 % mod << " (" << Answer1 << "," << Answer2 << ")" << endl;
    cout << endl;*/
    return Answer1 * Answer2 % mod;
}

// ================================================ Main Function ================================================
long long N;
long long R[1 << 19];
string S[1 << 19];

int main() {
    // Step 1. Input
    cin >> N;
    for (int i = 0; i < N; i++) cin >> R[i] >> S[i];
    vector<pair<string, long long>> Current;
    char CurrentFugo = '+';
    long long Answer = 0;

    // Step 2. Get Answer (Part 1)
    for (int i = 0; i < N; i++) {
        string str = "";
        for (int j = 0; j < (int)S[i].size(); j++) {
            if (S[i][j] == '+' || S[i][j] == '-') {
                Current.push_back(make_pair(str, 1));
                long long eval = Solve(Current);
                if (CurrentFugo == '+') Answer = (Answer + eval + mod) % mod;
                if (CurrentFugo == '-') Answer = (Answer - eval + mod) % mod;
                str = "";
                CurrentFugo = S[i][j];
                Current.clear();
            }
            else str += S[i][j];
        }
        if (str.size() == S[i].size()) Current.push_back(make_pair(str, R[i]));
        if (str.size() != S[i].size()) Current.push_back(make_pair(str, 1LL));
        if (i == N - 1) {
            long long eval = Solve(Current);
            if (CurrentFugo == '+') Answer = (Answer + eval + mod) % mod;
            if (CurrentFugo == '-') Answer = (Answer - eval + mod) % mod;
        }
    }

    // Step 3. Get Answer (Part 2)
    for (int i = 0; i < N; i++) {
        string str = "";
        char Fugo = '.';
        for (int j = 0; j < (int)S[i].size() * 2; j++) {
            if (S[i][j % S[i].size()] == '+' || S[i][j % S[i].size()] == '-') {
                if (Fugo != '.') {
                    long long eval = Solve(vector<pair<string, long long>>{make_pair(str, 1LL)});
                    long long tm = R[i] - 1;
                    eval = (eval * tm) % mod;
                    if (Fugo == '+') Answer = (Answer + eval + mod) % mod;
                    if (Fugo == '-') Answer = (Answer - eval + mod) % mod;
                }
                Fugo = S[i][j];
                str = "";
                if (j >= S[i].size()) break;
            }
            else str += S[i][j % S[i].size()];
        }
    }

    // Step 3. Output
    cout << Answer << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 21852
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int MOD = 1000000007;

class modint {
private:
	int x;
public:
	modint() : x(0) {}
	modint(long long n) : x(n >= 0 ? n % MOD : (n - (-n) % MOD) % MOD) {}
	int get() const { return x; }
	modint& operator+=(const modint& m) { x = (x + m.x) % MOD; return *this; }
	modint& operator*=(const modint& m) { x = 1LL * x * m.x % MOD; return *this; }
	modint operator+(const modint& m) const { return modint(*this) += m; }
	modint operator*(const modint& m) const { return modint(*this) *= m; }
	modint pow(long long b) const {
		modint a(*this);
		modint res(1);
		while (b >= 1) {
			if (b % 2 == 1) {
				res *= a;
			}
			a *= a;
			b /= 2;
		}
		return res;
	}
};

class value {
public:
	modint m; long long digits;
	value() : m(modint()), digits(0) {}
	value(const modint& m_, long long digits_) : m(m_), digits(digits_) {}
	string to_string() const {
		return "(" + std::to_string(m.get()) + "," + std::to_string(digits) + ")";
	}
};

// state type 0: l
// state type 1: l] * [a] * [r
// state type 2: l] * [a] + [b] + [c] * [r

class expression {
public:
	int tp;
	value l, r;
	modint a, b, c;
	expression() : tp(-1), l(value()), r(value()), a(modint()), b(modint()), c(modint()) {}
	expression(const value& l_) : tp(1), l(l_), r(value()), a(modint()), b(modint()), c(modint()) {}
	expression(const value& l_, const modint& a_, const value& r_) : tp(2), l(l_), r(r_), a(a_), b(modint()), c(modint()) {}
	expression(const value& l_, const modint& a_, const modint& b_, const modint& c_, const value& r_) : tp(3), l(l_), r(r_), a(a_), b(b_), c(c_) {}
	string to_string() const {
		if (tp == 1) {
			return "?" + l.to_string() + "?";
		}
		if (tp == 2) {
			return "?" + l.to_string() + "*" + std::to_string(a.get()) + "*" + r.to_string() + "?";
		}
		if (tp == 3) {
			return "?" + l.to_string() + "*" + std::to_string(a.get()) + "+" + std::to_string(b.get()) + "+" + std::to_string(c.get()) + "*" + r.to_string() + "?";
		}
		return string();
	}
};

value merge(const value& v1, const value& v2) {
	return value(v1.m * modint(10).pow(v2.digits) + v2.m, v1.digits + v2.digits);
}

expression merge(const expression& e1, const expression& e2) {
	if (e1.tp == 1 && e2.tp == 1) {
		return expression(merge(e1.l, e2.l));
	}
	if (e1.tp == 1 && e2.tp == 2) {
		return expression(merge(e1.l, e2.l), e2.a, e2.r);
	}
	if (e1.tp == 1 && e2.tp == 3) {
		return expression(merge(e1.l, e2.l), e2.a, e2.b, e2.c, e2.r);
	}
	if (e1.tp == 2 && e2.tp == 1) {
		return expression(e1.l, e1.a, merge(e1.r, e2.l));
	}
	if (e1.tp == 2 && e2.tp == 2) {
		return expression(e1.l, e1.a * merge(e1.r, e2.l).m * e2.a, e2.r);
	}
	// state type 0: l
	// state type 1: l] * [a] * [r
	// state type 2: l] * [a] + [b] + [c] * [r
	if (e1.tp == 2 && e2.tp == 3) {
		return expression(e1.l, e1.a * merge(e1.r, e2.l).m * e2.a, e2.b, e2.c, e2.r);
	}
	if (e1.tp == 3 && e2.tp == 1) {
		return expression(e1.l, e1.a, e1.b, e1.c, merge(e1.r, e2.l));
	}
	if (e1.tp == 3 && e2.tp == 2) {
		return expression(e1.l, e1.a, e1.b, e1.c * merge(e1.r, e2.l).m * e2.a, e2.r);
	}
	if (e1.tp == 3 && e2.tp == 3) {
		return expression(e1.l, e1.a, e1.b + e1.c * merge(e1.r, e2.l).m * e2.a + e2.b, e2.c, e2.r);
	}
	return expression();
}

string transform(string S) {
	string res;
	for (char c : S) {
		if (c != '-') {
			res += c;
		}
		else {
			res += "+" + to_string(MOD - 1) + "*";
		}
	}
	return res;
}

expression level0(const string& S) {
	modint x;
	for (char c : S) {
		x = x * 10 + int(c - '0');
	}
	return expression(value(x, S.size()));
}

expression level1(const string& S) {
	for (int i = int(S.size()) - 1; i >= 0; i--) {
		if (S[i] == '*') {
			expression lc = level1(S.substr(0, i));
			expression rc = level0(S.substr(i + 1));
			expression mc(value(), modint(1), value());
			return merge(merge(lc, mc), rc);
		}
	}
	return level0(S);
}

expression level2(const string& S) {
	for (int i = int(S.size()) - 1; i >= 0; i--) {
		if (S[i] == '+') {
			expression lc = level2(S.substr(0, i));
			expression rc = level1(S.substr(i + 1));
			expression mc(value(), modint(1), modint(0), modint(1), value());
			return merge(merge(lc, mc), rc);
		}
	}
	return level1(S);
}

int main() {
	int N;
	cin >> N;
	vector<int> R(N);
	vector<string> S(N);
	for (int i = 0; i < N; i++) {
		cin >> R[i] >> S[i];
		S[i] = transform(S[i]);
	}
	vector<expression> E(N);
	for (int i = 0; i < N; i++) {
		E[i] = level2(S[i]);
	}
	vector<expression> F(N, expression(value()));
	for (int i = 0; i < N; i++) {
		expression e = E[i];
		int b = R[i];
		while (b >= 1) {
			if (b % 2 == 1) {
				F[i] = merge(F[i], e);
			}
			e = merge(e, e);
			b /= 2;
		}
	}
	expression result = expression(value());
	for (int i = 0; i < N; i++) {
		result = merge(result, F[i]);
	}
	expression aux(value(), modint(1), modint(0), modint(1), value());
	expression ans = merge(merge(aux, result), aux);
	modint final_ans = ans.b;
	cout << final_ans.get() << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5032
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
#define all(p) p.begin(),p.end()
const int mod=1e9+7;

/*
前から見る
A = 今の答え
B = 今の積
C = 一個前までのやつ

num
B' <- B * 10 + C * num

+
A' <- A + B
B' <- 1
C' <- 1

-
A' <- A + B
B' <- -1
C' <- -1

*
B' <- 0
C' <- B

*/

int main(){
	auto e=[&]()->vector<vector<ll>>{
		vector<vector<ll>> p(4,vector<ll>(4));
		rep(i,0,4) p[i][i]=1;
		return p;
	};
	auto f=[&](vector<vector<ll>> l,vector<vector<ll>> r)->vector<vector<ll>>{
		vector<vector<ll>> p(4,vector<ll>(4));
		rep(i,0,4) rep(j,0,4) rep(k,0,4){
			p[i][k]=(p[i][k]+l[i][j]*r[j][k])%mod;
		}
		return p;
	};
	auto pow_f=[&](vector<vector<ll>> l,int x)->vector<vector<ll>>{
		auto p=e();
		while(x){
			if(x&1) p=f(p,l);
			x/=2;
			l=f(l,l);
		}
		return p;
	};
	auto ans=e();
	int N;
	cin>>N;
	rep(i,0,N+1){
		int x;
		string S;
		if(i==N) x=1,S='+';
		else cin>>x>>S;
		auto tmp=e();
		auto val=e();
		for(auto c:S){
			if(c=='+'){
				val={
					{1,0,0,0},
					{1,0,0,0},
					{0,0,0,0},
					{0,0,1,1}
				};
			}else if(c=='-'){
				val={
					{1,0,0,0},
					{1,0,0,0},
					{0,0,0,0},
					{0,0,-1,1}
				};
			}else if(c=='*'){
				val={
					{1,0,0,0},
					{0,0,1,0},
					{0,0,0,0},
					{0,0,0,1}
				};
			}else{
				val={
					{1,0,0,0},
					{0,10,0,0},
					{0,c-'0',1,0},
					{0,0,0,1}
				};
			}
			tmp=f(tmp,val);
		}
		tmp=pow_f(tmp,x);
		ans=f(ans,tmp);
	}
	cout<<(ans[2][0]+ans[3][0]+mod+mod)%mod<<"\n";
}
accuracy: 1
time_ms: 170
memory_kb: 3460
final_rank: 12

code_snippet: //#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 2;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

struct num {
	modint val;
	modint coef;
};

struct Data {
	vector<num> vn;
	vector<char> vc;
};

num merge(num a, num b) {
	return { a.val * b.coef + b.val,a.coef * b.coef };
}

modint calc(vector<num> vn, vector<char> vc) {
	modint res = 0;
	modint cur = vn[0].val;
	rep(i, vc.size()) {
		if (vc[i] == '*') {
			cur*= vn[i + 1].val;
		}
		else {
			res += cur;
			cur = vn[i + 1].val;
			if (vc[i] == '-')cur *= -1;
		}
	}
	res += cur;
	return res;
}
Data merge(Data a, Data b) {
	vector<num> vn;
	vector<char> vc;
	rep(i, a.vn.size())vn.push_back(a.vn[i]);
	vn.back() = merge(vn.back(), b.vn[0]);
	for (int i = 1; i < b.vn.size(); i++)vn.push_back(b.vn[i]);
	rep(i, a.vc.size())vc.push_back(a.vc[i]);
	rep(i, b.vc.size())vc.push_back(b.vc[i]);
	int cnt = 0;
	rep(i, vc.size()) {
		if (vc[i] == '+' || vc[i] == '-')cnt++;
	}
	if (cnt == 0) {
		if (vc.size() >= 3) {
			vector<num> nvn;
			vector<char> nvc;
			nvc = { '*','*' };
			nvn.push_back(vn[0]);
			modint pro = 1;
			for (int i = 1; i < vn.size() - 1; i++) {
				pro *= vn[i].val;
			}
			nvn.push_back({ pro,1 });
			nvn.push_back(vn.back());
			swap(vn, nvn);
			swap(vc, nvc);
		}
		else {
			//
		}
	}
	else if (cnt == 1) {
		while (vc.size() >= 2 && vc[0]=='*'&&vc[1] == '*') {
			modint pro = vn[1].val * vn[2].val;
			vn.erase(vn.begin() + 2);
			vn[1] = { pro,1 };
			vc.erase(vc.begin() + 1);
		}
		while (vc.size() >= 2 && vc[vc.size() - 2] == '*' && vc[vc.size() - 1] == '*') {
			modint pro = vn[vn.size() - 3].val * vn[vn.size() - 2].val;
			vn[vn.size() - 2] = { pro,1 };
			vn.erase(vn.begin() + (vn.size() - 3));
			vc.erase(vc.begin() + (vc.size() - 2));
		}
		/*rep(i, vc.size())if (vc[i] != '*') {
			if (i >= 2) {
				modint pro = 1;
				for (int j = 1; j <= i; j++) {
					pro *= vn[j].val;
				}
				vn[1] = { pro,1 };
				vn.erase(vn.begin() + 2, vn.begin() + i + 1);
				vc.erase(vc.begin() + 2, vc.begin() + i);
			}
			break;
		}*/
		/*per(i, vc.size())if (vc[i] != '*') {
			if (vc.size() - i >= 3) {

			}
			break;
		}*/
	}
	else {
		while (vc.size() >= 2 && vc[0] == '*' && vc[1] == '*') {
			modint pro = vn[1].val * vn[2].val;
			vn.erase(vn.begin() + 2);
			vn[1] = { pro,1 };
			vc.erase(vc.begin() + 1);
		}
		while (vc.size() >= 2 && vc[vc.size() - 2] == '*' && vc[vc.size() - 1] == '*') {
			modint pro = vn[vn.size() - 3].val * vn[vn.size() - 2].val;
			vn[vn.size() - 2] = { pro,1 };
			vn.erase(vn.begin() + (vn.size() - 3));
			vc.erase(vc.begin() + (vc.size() - 2));
		}
		int cl, cr;
		rep(i, vc.size())if (vc[i] != '*') {
			cl = i; break;
		}
		per(i, vc.size())if (vc[i] != '*') {
			cr = i; break;
		}
		//vn...[cl+1,cr]
		//vc...[cl+1,cr-1]
		if (vc[cl] == '-') {
			vc[cl] = '+';
			vn[cl + 1].val *= -1;
		}
		vector<num> subn;
		vector<char> subc;
		Rep1(j, cl + 1, cr)subn.push_back(vn[j]);
		Rep1(j, cl + 1, cr - 1) subc.push_back(vc[j]);
		modint val = calc(subn,subc);
		vn.erase(vn.begin() + cl + 1, vn.begin()+cr+1);
		vn.insert(vn.begin() + cl + 1, { val,1 });
		vc.erase(vc.begin() + cl + 1, vc.begin() + cr);
	}
	return { vn,vc };
}

Data trans(char c) {
	vector<num> vn;
	vector<char> vc;
	if (c == '*'||c=='+'||c=='-') {
		vn.push_back({ 0,1 });
		vn.push_back({ 0,1 });
		vc.push_back(c);
	}
	else {
		vn.push_back({ c - '0',10 });
	}
	return { vn,vc };
}
void solve() {
	int n; cin >> n;
	Data e;
	e.vn.push_back({ 0,1 });
	Data cur = e;
	rep(i, n) {
		int r; cin >> r;
		string s; cin >> s;
		Data nw = e;
		for (char c : s) {
			Data nex = trans(c);
			nw = merge(nw, nex);
		}
		Data x = e;
		rep(t, 30) {
			if (r & (1 << t))x = merge(x, nw);
			nw = merge(nw, nw);
		}
		cur = merge(cur, x);
	}
	modint ans = calc(cur.vn,cur.vc);
	cout << ans << "\n";
}



signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(8);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3508
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define LL long long
#define PII pair<int,int>
#define _for(i,j,k) for(int i=j;i<=k;i++)
#define for_(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) (x&-x)
#define ls(x) x<<1
#define rs(x) x<<1|1
#define inf 0x3f3f3f3f
#define localtest freopen("E:/ACM/2020/input.txt","r",stdin);
const int maxn = 1e4 + 5;
const LL mod = 1e9 + 7;
int n;
map<char, LL> pmap;
LL mp(LL x,LL y){
    x %= mod;
    LL ret = 1ll;
    for (; y;y>>=1,x=(LL)x*x%mod)
    if(y&1)
        ret = (LL)ret * x % mod;
    return ret % mod;
}
LL inv(LL x){
    return mp(x, mod - 2);
}
string num2str(LL num){
    string s="";
    while(num){
        s += (num % 10 + '0');
        num /= 10;
    }
    reverse(s.begin(),s.end());
    return s;
}
LL str2num(string& s){
    LL num = 0;
    int len = s.length();
    for (int i = 0; i < len;i++){
        num = 10ll * num % mod + (s[i] - '0');
        num %= mod;
    }
    return num;
}
LL pro(string& s,bool fg){
    vector<LL> v;
    v.clear();
    //if(s.length()<=0)
    //    return 0;
    v.push_back(s[0] - '0');
    int len = s.length(), p = 0;
    for (int i = 1; i < len;i++){
        if(isdigit(s[i])){
            if(v[p]>=0){
                v[p] = 10ll * v[p] % mod + (s[i] - '0');
                v[p] %= mod;
            }
            else{
                ++p;
                v.push_back(s[i] - '0');
            }
        }
        else{
            ++p;
            v.push_back(pmap[s[i]]);
        }
    }
    if(fg)
        v[0] = (LL)(mod - v[0]) % mod;
    vector<LL> u;
    u.push_back(v[0]);
    int cnt = 0;
    for (int i = 1; i <= p;i++){
        if(u[cnt]==-1){
            u.pop_back();
            cnt--;
            LL tmp = u[cnt];
            u.pop_back();
            cnt--;
            tmp = (LL)tmp * v[i] % mod;
            u.push_back(tmp);
            cnt++;
        }
        else{
            u.push_back(v[i]);
            cnt++;
        }
    }
    LL f = 1;
    LL ret = u[0];
    for (int i = 1; i <= cnt;i+=2){
        if(u[i]==-2){
            ret = (LL)(ret + f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
        else{
            ret = (LL)(ret - f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
    }
    return ret;
}
int main(){
    //localtest
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    pmap['*'] = -1;
    pmap['+'] = -2;
    pmap['-'] = -3;
    cin >> n;
    string str="", s;
    LL r = 0;
    _for(i,1,n){
        cin >> r >> s;
        if(r==1){
            str += s;
        }
        else{
            //_for(j, 1, r) str += s;
            int len = s.length(),pos=-1;
            _for(j,0,len-1){
                if(s[j]=='+'){
                    pos = j;
                    break;
                }
            }
            if(pos!=-1){
                string ss = "";
                _for(j,pos+1,len-1){
                    ss += s[j];
                }
                _for(j,0,pos-1){
                    ss += s[j];
                }
                LL tmp = pro(ss,0);
                tmp = (LL)(r - 1) % mod * tmp % mod;
                //if(s[pos]=='-') tmp = (LL)(mod - tmp) % mod;
                _for(j,0,pos){
                    str += s[j];
                }
                str += num2str(tmp);
                _for(j,pos,len-1){
                    str += s[j];
                }
            }
            else{
                _for(j,0,len-1){
                    if(s[j]=='-'){
                        pos = j;
                        break;
                    }
                }
                if(pos!=-1){
                    string ss = "";
                    _for(j,pos+1,len-1){
                        ss += s[j];
                    }
                    _for(j,0,pos-1){
                        ss += s[j];
                    }
                    LL tmp = pro(ss,1);
                    tmp = (LL)(r - 1) % mod * tmp % mod;
                    //if(s[pos]=='-') tmp = (LL)(mod - tmp) % mod;
                    _for(j,0,pos-1){
                        str += s[j];
                    }
                    str += '+';
                    str += num2str(tmp);
                    _for(j,pos,len-1){
                        str += s[j];
                    }
                }
                else{
                    _for(j,0,len-1){
                        if(s[j]=='*'){
                            pos = j;
                            break;
                        }
                    }
                    if(pos!=-1){
                        string ss = "";
                        _for(j,pos+1,len-1){
                            ss += s[j];
                        }
                        _for(j,0,pos-1){
                            ss += s[j];
                        }
                        LL tmp = pro(ss,0);
                        tmp = mp(tmp, r - 1);
                        _for(j,0,pos){
                            str += s[j];
                        }
                        str += num2str(tmp);
                        _for(j,pos,len-1){
                            str += s[j];
                        }
                    }
                    else{
                        LL tmp = str2num(s);
                        tmp = (LL)(mp(10, (LL)len * r) - 1 + mod) % mod * tmp % mod;
                        tmp = (LL)tmp * inv((mp(10, len) - 1 + mod) % mod) % mod;
                        int l = str.length() - 1;
                        string tmps = "";
                        if(isdigit(str[l])){
                            while(isdigit(str[l])){
                                tmps += str[l];
                                str.erase(l);
                                l--;
                            }
                            reverse(tmps.begin(), tmps.end());
                            //cout << "tmps:" << tmps << "\n";
                            //cout << "tmp:" << tmp << "\n";
                            LL num = str2num(tmps);
                            //cout << "num:" << num << "\n";
                            num = (LL)mp(10, (LL)len * r) * num % mod;
                            //cout << "num:" << num << "\n";
                            num = (LL)(num + tmp) % mod;
                            str += num2str(num);
                        }
                        else{
                            str += num2str(tmp);
                        }
                    }
                }
            }
        }
        //cout << str << "\n";
        //cout << pro(str,0) << "\n";
    }
    
    cout << pro(str,0) << "\n";

    return 0;
}
/*
5
900 5+3*11-3*3+55
1 45+45-33+100
44 04+40
9 9*9*9*10
8 01340
205143968

4
999 100+
9999 010
99999 *100
999999 00200
389822449
*/
accuracy: 0.3877551020408163
time_ms: 10
memory_kb: 4384
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define LL long long
#define PII pair<int,int>
#define _for(i,j,k) for(int i=j;i<=k;i++)
#define for_(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) (x&-x)
#define ls(x) x<<1
#define rs(x) x<<1|1
#define inf 0x3f3f3f3f
#define localtest freopen("E:/ACM/2020/input.txt","r",stdin);
const int maxn = 1e4 + 5;
const LL mod = 1e9 + 7;
int n;
map<char, LL> pmap;
LL mp(LL x,LL y){
    x %= mod;
    LL ret = 1ll;
    for (; y;y>>=1,x=(LL)x*x%mod)
    if(y&1)
        ret = (LL)ret * x % mod;
    return ret % mod;
}
LL inv(LL x){
    return mp(x, mod - 2);
}
string num2str(LL num){
    string s="";
    while(num){
        s += (num % 10 + '0');
        num /= 10;
    }
    reverse(s.begin(),s.end());
    return s;
}
LL str2num(string& s){
    LL num = 0;
    int len = s.length();
    for (int i = 0; i < len;i++){
        num = 10ll * num % mod + (s[i] - '0');
        num %= mod;
    }
    return num;
}
LL pro(string& s,bool fg){
    vector<LL> v;
    v.clear();
    //if(s.length()<=0)
    //    return 0;
    v.push_back(s[0] - '0');
    int len = s.length(), p = 0;
    for (int i = 1; i < len;i++){
        if(isdigit(s[i])){
            if(v[p]>=0){
                v[p] = 10ll * v[p] % mod + (s[i] - '0');
                v[p] %= mod;
            }
            else{
                ++p;
                v.push_back(s[i] - '0');
            }
        }
        else{
            ++p;
            v.push_back(pmap[s[i]]);
        }
    }
    vector<LL> u;
    u.push_back(v[0]);
    int cnt = 0;
    for (int i = 1; i <= p;i++){
        if(u[cnt]==-1){
            u.pop_back();
            cnt--;
            LL tmp = u[cnt];
            u.pop_back();
            cnt--;
            tmp = (LL)tmp * v[i] % mod;
            u.push_back(tmp);
            cnt++;
        }
        else{
            u.push_back(v[i]);
            cnt++;
        }
    }
    LL f = fg ? -1 : 1;
    LL ret = u[0];
    for (int i = 1; i <= cnt;i+=2){
        if(u[i]==-2){
            ret = (LL)(ret + f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
        else{
            ret = (LL)(ret - f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
    }
    return ret;
}
int main(){
    //localtest
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    pmap['*'] = -1;
    pmap['+'] = -2;
    pmap['-'] = -3;
    cin >> n;
    string str="", s;
    LL r = 0;
    _for(i,1,n){
        cin >> r >> s;
        if(r==1){
            str += s;
        }
        else{
            //_for(j, 1, r) str += s;
            int len = s.length(),pos=-1;
            _for(j,0,len-1){
                if(s[j]=='+'){
                    pos = j;
                    break;
                }
            }
            if(pos!=-1){
                string ss = "";
                _for(j,pos+1,len-1){
                    ss += s[j];
                }
                _for(j,0,pos-1){
                    ss += s[j];
                }
                LL tmp = pro(ss,0);
                tmp = (LL)(r - 1) % mod * tmp % mod;
                //if(s[pos]=='-') tmp = (LL)(mod - tmp) % mod;
                _for(j,0,pos){
                    str += s[j];
                }
                str += num2str(tmp);
                _for(j,pos,len-1){
                    str += s[j];
                }
            }
            else{
                _for(j,0,len-1){
                    if(s[j]=='-'){
                        pos = j;
                        break;
                    }
                }
                if(pos!=-1){
                    string ss = "";
                    _for(j,pos+1,len-1){
                        ss += s[j];
                    }
                    _for(j,0,pos-1){
                        ss += s[j];
                    }
                    LL tmp = pro(ss,1);
                    tmp = (LL)(r - 1) % mod * tmp % mod;
                    //if(s[pos]=='-') tmp = (LL)(mod - tmp) % mod;
                    _for(j,0,pos){
                        str += s[j];
                    }
                    str += num2str(tmp);
                    _for(j,pos,len-1){
                        str += s[j];
                    }
                }
                else{
                    _for(j,0,len-1){
                        if(s[j]=='*'){
                            pos = j;
                            break;
                        }
                    }
                    if(pos!=-1){
                        string ss = "";
                        _for(j,pos+1,len-1){
                            ss += s[j];
                        }
                        _for(j,0,pos-1){
                            ss += s[j];
                        }
                        LL tmp = pro(ss,0);
                        tmp = mp(tmp, r - 1);
                        _for(j,0,pos){
                            str += s[j];
                        }
                        str += num2str(tmp);
                        _for(j,pos,len-1){
                            str += s[j];
                        }
                    }
                    else{
                        LL tmp = str2num(s);
                        tmp = (LL)(mp(10, (LL)len * r) - 1 + mod) % mod * tmp % mod;
                        tmp = (LL)tmp * inv((mp(10, len) - 1 + mod) % mod) % mod;
                        int l = str.length() - 1;
                        string tmps = "";
                        if(isdigit(str[l])){
                            while(isdigit(str[l])){
                                tmps += str[l];
                                str.erase(l);
                                l--;
                            }
                            reverse(tmps.begin(), tmps.end());
                            //cout << "tmps:" << tmps << "\n";
                            //cout << "tmp:" << tmp << "\n";
                            LL num = str2num(tmps);
                            //cout << "num:" << num << "\n";
                            num = (LL)mp(10, (LL)len * r) * num % mod;
                            //cout << "num:" << num << "\n";
                            num = (LL)(num + tmp) % mod;
                            str += num2str(num);
                        }
                        else{
                            str += num2str(tmp);
                        }
                    }
                }
            }
        }
        //cout << str << "\n";
        //cout << pro(str,0) << "\n";
    }
    
    cout << pro(str,0) << "\n";

    return 0;
}
/*
5
900 5+3*11-3*3+55
1 45+45-33+100
44 04+40
9 9*9*9*10
8 01340
205143968

4
999 100+
9999 010
99999 *100
999999 00200
389822449
*/
accuracy: 0.3877551020408163
time_ms: 10
memory_kb: 4564
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define LL long long
#define PII pair<int,int>
#define _for(i,j,k) for(int i=j;i<=k;i++)
#define for_(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) (x&-x)
#define ls(x) x<<1
#define rs(x) x<<1|1
#define inf 0x3f3f3f3f
const int maxn = 1e4 + 5;
const LL mod = 1e9 + 7;
int n;
map<char, LL> pmap;
LL mp(LL x,LL y){
    x %= mod;
    LL ret = 1ll;
    for (; y;y>>=1,x=(LL)x*x%mod)
    if(y&1)
        ret = (LL)ret * x % mod;
    return ret % mod;
}
LL inv(LL x){
    return mp(x, mod - 2);
}
string num2str(LL num){
    string s="";
    while(num){
        s += (num % 10 + '0');
        num /= 10;
    }
    reverse(s.begin(),s.end());
    return s;
}
LL str2num(string& s){
    LL num = 0;
    int len = s.length();
    for (int i = 0; i < len;i++){
        num = 10ll * num % mod + (s[i] - '0');
        num %= mod;
    }
    return num;
}
LL pro(string& s,bool fg){
    vector<LL> v;
    v.clear();
    //if(s.length()<=0)
    //    return 0;
    v.push_back(s[0] - '0');
    int len = s.length(), p = 0;
    for (int i = 1; i < len;i++){
        if(isdigit(s[i])){
            if(v[p]>=0){
                v[p] = 10ll * v[p] % mod + (s[i] - '0');
                v[p] %= mod;
            }
            else{
                ++p;
                v.push_back(s[i] - '0');
            }
        }
        else{
            ++p;
            v.push_back(pmap[s[i]]);
        }
    }
    vector<LL> u;
    u.push_back(v[0]);
    int cnt = 0;
    for (int i = 1; i <= p;i++){
        if(u[cnt]==-1){
            u.pop_back();
            cnt--;
            LL tmp = u[cnt];
            u.pop_back();
            cnt--;
            tmp = (LL)tmp * v[i] % mod;
            u.push_back(tmp);
            cnt++;
        }
        else{
            u.push_back(v[i]);
            cnt++;
        }
    }
    LL f = fg ? -1 : 1;
    LL ret = u[0];
    for (int i = 1; i <= cnt;i+=2){
        if(u[i]==-2){
            ret = (LL)(ret + f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
        else{
            ret = (LL)(ret - f*u[i + 1]) % mod;
            ret = (LL)(ret + mod) % mod;
        }
    }
    return ret;
}
int main(){
    //localtest
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    pmap['*'] = -1;
    pmap['+'] = -2;
    pmap['-'] = -3;
    cin >> n;
    string str="", s;
    LL r = 0;
    _for(i,1,n){
        cin >> r >> s;
        if(r==1){
            str += s;
        }
        else{
            //_for(j, 1, r) str += s;
            int len = s.length(),pos=-1;
            _for(j,0,len-1){
                if(s[j]=='+'||s[j]=='-'){
                    pos = j;
                    break;
                }
            }
            if(pos!=-1){
                string ss = "";
                _for(j,pos+1,len-1){
                    ss += s[j];
                }
                _for(j,0,pos-1){
                    ss += s[j];
                }
                LL tmp = pro(ss,s[pos]=='-');
                tmp = (LL)(r - 1) % mod * tmp % mod;
                //if(s[pos]=='-') tmp = (LL)(mod - tmp) % mod;
                _for(j,0,pos){
                    str += s[j];
                }
                str += num2str(tmp);
                _for(j,pos,len-1){
                    str += s[j];
                }
            }
            else{
                _for(j,0,len-1){
                    if(s[j]=='*'){
                        pos = j;
                        break;
                    }
                }
                if(pos!=-1){
                    string ss = "";
                    _for(j,pos+1,len-1){
                        ss += s[j];
                    }
                    _for(j,0,pos-1){
                        ss += s[j];
                    }
                    LL tmp = pro(ss,0);
                    tmp = mp(tmp, r - 1);
                    _for(j,0,pos){
                        str += s[j];
                    }
                    str += num2str(tmp);
                    _for(j,pos,len-1){
                        str += s[j];
                    }
                }
                else{
                    LL tmp = str2num(s);
                    tmp = (LL)(mp(10, (LL)len * r) - 1 + mod) % mod * tmp % mod;
                    tmp = (LL)tmp * inv((mp(10, len) - 1 + mod) % mod) % mod;
                    int l = str.length() - 1;
                    string tmps = "";
                    if(isdigit(str[l])){
                        while(isdigit(str[l])){
                            tmps += str[l];
                            str.erase(l);
                            l--;
                        }
                        reverse(tmps.begin(), tmps.end());
                        //cout << "tmps:" << tmps << "\n";
                        //cout << "tmp:" << tmp << "\n";
                        LL num = str2num(tmps);
                        //cout << "num:" << num << "\n";
                        num = (LL)mp(10, (LL)len * r) * num % mod;
                        //cout << "num:" << num << "\n";
                        num = (LL)(num + tmp) % mod;
                        str += num2str(num);
                    }
                    else{
                        str += num2str(tmp);
                    }
                }
            }
        }
        //cout << str << "\n";
        //cout << pro(str,0) << "\n";
    }
    
    cout << pro(str,0) << "\n";

    return 0;
}
/*
5
900 5+3*11-3*3+55
1 45+45-33+100
44 04+40
9 9*9*9*10
8 01340
205143968

4
999 100+
9999 010
99999 *100
999999 00200
389822449
*/
accuracy: 0.3877551020408163
time_ms: 10
memory_kb: 4396
final_rank: 17

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



int N;
char buf[11];

typedef vector<ll> V;
typedef vector<V> MATRIX;

int SIZE = 2;
ll MOD_POW[11];


ll mod_pow(ll x,ll n, ll mod){

	if(n == 0)return 1;
	ll ret = mod_pow(x*x%mod,n/2,mod);
	if(n%2 == 1)ret = ret*x%mod;
	return ret;
}


MATRIX calc(MATRIX left,MATRIX right){

	MATRIX ret(SIZE,V(SIZE));

	for(int i = 0; i < SIZE; i++){
		for(int k = 0; k < SIZE; k++)ret[i][k] = 0;
	}

	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){
			for(int a = 0; a < SIZE; a++){
				ret[row][col] += left[row][a]*right[a][col]%MOD;
			}
		}
	}

	return ret;

}

//MULTのT乗を計算する
MATRIX POW(MATRIX MULT,int count){

	MATRIX ret(SIZE,V(SIZE));

	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){
			if(row == col)ret[row][col] = 1;
			else{
				ret[row][col] = 0;
			}
		}
	}

	while(count > 0){
		if(count%2 == 1)ret = calc(ret,MULT);
		MULT = calc(MULT,MULT);
		count /= 2;
	}

	return ret;
}

int main(){

	MOD_POW[0] = 1;

	for(int i = 1; i <= 10; i++){

		MOD_POW[i] = (MOD_POW[i-1]*10)%MOD;
	}

	scanf("%d",&N);

	queue<ll> NUM,MULT;
	queue<char> OP;

	NUM.push(0);
	OP.push('+');

	int rep_num;
	ll last_num = 0,length;
	bool is_last_num = false;
	char last_op = '+';

	bool is_op,is_plus_minus;

	for(int loop = 0; loop < N; loop++){

		scanf("%d %s",&rep_num,buf);

		is_op = false;
		is_plus_minus = false;

		for(length = 0; buf[length] != '\0'; length++){

			switch(buf[length]){
			case '+':
			case '-':
				is_op = true;
				is_plus_minus = true;
				break;
			case '*':
				is_op = true;
				break;
			default: //数字
				//Do nothing
				break;
			}
		}

		if(!is_op){ //数字のみの場合

			ll num = 0;

			for(int i = 0; i < length; i++){

				num = 10*num+(buf[i]-'0');
				num %= MOD;
			}

			MATRIX first(2,V(1));

			if(is_last_num){ //文字列の最後が数字の場合

				first[0][0] = last_num;

			}else{ //文字列の最後が演算子の場合

				first[0][0] = 0;
			}

			first[0][1] = 1;

			MATRIX A(SIZE,V(SIZE));
			A[0][0] = MOD_POW[length];
			A[0][1] = num;

			A[1][0] = 0;
			A[1][1] = 1;

			A = POW(A,rep_num);

			last_num = (A[0][0]*first[0][0]+A[0][1])%MOD;

			is_last_num = true;

		}else{

			if(!is_plus_minus){ //*のみの場合

				int first_loc;

				for(int i = 0; i < length; i++){

					if(buf[i] == '*'){

						first_loc = i;
						break;
					}
				}

				ll L;

				if(first_loc > 0){ //最初の*の左の数字

					ll tmp = 0;
					for(int i = 0; i < first_loc; i++){

						tmp = 10*tmp + (buf[i]-'0');
						tmp %= MOD;
					}

					if(is_last_num){

						tmp = last_num*MOD_POW[first_loc]+tmp; //左にシフトさせて足す
						tmp %= MOD;

						L = tmp;

					}else{ //前の文字列の最後が演算子

						if(last_op == '*'){ //数字確定

							MULT.push(tmp);
							L = 1;

						}else{ //★注意★

							L = tmp;
						}
					}

				}else{ //first_loc == 0

					L = last_num; //必ずis_last_num == trueであるはず
				}

				ll tmp = 0;
				stack<ll> tmp_MULT;

				if(rep_num == 1){

					MULT.push(L);

					ll work = 0;

					int last_loc;
					for(int i = length-1; i >= 0; i--){
						if(buf[i] == '*'){
							last_loc = i;
							break;
						}
					}

					for(int i = first_loc+1; i < last_loc; i++){

						if(buf[i] == '*'){
							MULT.push(work);
							work = 0;
						}else{

							work = 10*work+(buf[i]-'0');
							work %= MOD;

							if(i+1 == last_loc){

								MULT.push(work);
							}
						}
					}

					last_num = 0;
					for(int i = last_loc+1; i < length; i++){

						last_num = 10*last_num+(buf[i]-'0');
						last_num %= MOD;
					}

					if(last_loc == length-1){

						is_last_num = false;
					}else{

						is_last_num = true;
					}

					last_op = '*';
					continue;
				}

				for(int i = first_loc+1; i < length; i++){

					if(buf[i] == '*'){

						tmp_MULT.push(tmp);
						tmp = 0;

					}else{

						tmp = 10*tmp+(buf[i]-'0');
						tmp %= MOD;
					}
				}

				for(int i = 0; i < first_loc; i++){

					tmp = 10*tmp+(buf[i]-'0');
					tmp %= MOD;
				}
				tmp_MULT.push(tmp);

				ll A = 1;

				while(!tmp_MULT.empty()){

					A *= tmp_MULT.top();
					A %= MOD;
					tmp_MULT.pop();
				}

				if(rep_num > 1){

					A = mod_pow(A,rep_num-1,MOD);
					A *= L;
					A %= MOD;
					MULT.push(A); //最後のopは'*'なので
				}

				//★first_loc+1からlengthまでに*があるか調べる
				int last_loc;
				for(int i = length-1; i >= 0; i--){
					if(buf[i] == '*'){

						last_loc = i;
						break;
					}
				}

				if(last_loc == first_loc){

					if(buf[length-1] == '*'){ //first_loc==last_loc == length-1

						last_num = A;
						is_last_num = false;
					}else{

						last_num = 0;
						for(int i = last_loc+1; i < length; i++){

							last_num = 10*last_num+(buf[i]-'0');
							last_num %= MOD;
						}

						is_last_num = true;
					}

				}else{ //last_loc != first_loc

					ll work = 0;
					stack<ll> work_num;

					for(int i = first_loc+1; i < last_loc; i++){

						if(buf[i] == '*'){

							work_num.push(work);
							work = 0;
						}else{

							work = 10*work+(buf[i]-'0');
							work %= MOD;
							if(i+1 == last_loc){

								work_num.push(work);
							}
						}
					}

					ll D = work_num.top();
					work_num.pop();

					while(!work_num.empty()){

						D *= work_num.top();
						D %= MOD;
						work_num.pop();
					}

					MULT.push(D);

					last_num = 0;

					for(int i = last_loc+1; i < length; i++){

						last_num = 10*last_num+(buf[i]-'0');
						last_num %= MOD;
					}

					if('0' <= buf[length-1] && '9' >= buf[length-1]){

						is_last_num = true;
					}else{

						is_last_num = false;
					}
				}

				last_op = '*';

			}else{ //+か-が出現する場合

				int first_loc;

				for(int i = 0; i < length; i++){

					if(buf[i] == '+' || buf[i] == '-'){

						first_loc = i;
						break;
					}
				}

				//★★*が混ざっている可能性あり★★
				ll L,work = 0;
				stack<ll> work_num;

				for(int i = 0; i < first_loc; i++){

					if(buf[i] == '*'){

						if(work_num.empty()){ //初めての'*'

							if(is_last_num){ //数字が前から続いている場合

								work = last_num*MOD_POW[i]+work;
								work %= MOD;
								work_num.push(work);

							}else{ //前の文字列が演算子で終了している場合

								work_num.push(work);
							}

						}else{ //2つめ以降の'*';

							work_num.push(work);
						}

						work = 0;

					}else{

						//first_locの左は必ず数字であるはず
						work = 10*work+(buf[i]-'0');
						work %= MOD;

						if(i+1 == first_loc){

							if(work_num.empty()){ //★★

								if(is_last_num){ //数字が前から続いている場合

									work = last_num*MOD_POW[i+1]+work;
									work %= MOD;
								}
							}
						}
					}
				}

				while(!work_num.empty()){

					work *= work_num.top();
					work %= MOD;
					work_num.pop();
				}

				if(first_loc == 0){

					work = last_num; //★★
				}

				if(last_op == '*'){ //数字を連結させる

					MULT.push(work);

					ll tmp = 1;

					while(!MULT.empty()){

						tmp *= MULT.front();
						tmp %= MOD;
						MULT.pop();
					}

					NUM.push(tmp);

				}else{ //プラスかマイナス

					NUM.push(work);
				}

				if(rep_num > 1){

					OP.push('+'); //★★掛け算の準備★★
				}else{

					int last_loc;
					for(int i = length-1; i >= 0; i--){
						if(buf[i] == '+' || buf[i] == '-'){
							last_loc = i;
							break;
						}
					}

					if(last_loc == first_loc){

						OP.push(buf[first_loc]);
					}else{

						OP.push('+'); //追いかけの数字は'-'を反映させる
					}
				}

				//first_loc間の計算値を求め、掛け算に持ち込む

				char work_buf[11];
				int work_index = 0;

				stack<char> work_op;
				stack<ll> calc_num;
				stack<char> calc_op;

				int last_loc;

				for(int i = length-1; i >= 0; i--){

					if(buf[i] == '+' || buf[i] == '-'){
						last_loc = i;
						break;
					}
				}

				if(rep_num > 1){

					for(int i = first_loc+1; i < length; i++){

						work_buf[work_index++] = buf[i];
					}
					for(int i = 0; i < first_loc; i++){

						work_buf[work_index++] = buf[i];
					}

					work_num.push(0);
					work_op.push(buf[first_loc]);

					work = 0;

					for(int i = 0; i < work_index; i++){

						if(work_buf[i] == '*' || work_buf[i] == '+' || work_buf[i] == '-'){

							if(work_op.empty() == false && work_op.top() == '*'){

								work *= work_num.top();
								work %= MOD;
								work_num.pop();
								work_op.pop();
							}

							work_num.push(work);
							work_op.push(work_buf[i]);
							work = 0;

						}else{

							work = 10*work+(work_buf[i]-'0');
							work %= MOD;

							if(i+1 == work_index){

								if(work_op.empty() == false && work_op.top() == '*'){

									work *= work_num.top();
									work %= MOD;
									work_num.pop();
									work_op.pop();
								}

								work_num.push(work);
							}
						}
					}
					//このままだと右結合になってしまうので左結合にする

					while(!work_num.empty()){

						calc_num.push(work_num.top());
						work_num.pop();
					}

					while(!work_op.empty()){

						calc_op.push(work_op.top());
						work_op.pop();
					}

					ll A = calc_num.top();
					calc_num.pop();

					while(!calc_op.empty()){
						if(calc_op.top() == '+'){

							A += calc_num.top();
							A %= MOD;

						}else{

							A -= calc_num.top();
							if(A < 0)A += MOD;
						}
						calc_op.pop();
						calc_num.pop();
					}

					A *= rep_num-1;
					A %= MOD;

					NUM.push(A);

					if(last_loc != first_loc){
						OP.push('+');  //★★注意→追いかけで突っ込む数字はマイナスを反映させる★★
					}else{
						OP.push(buf[first_loc]);
					}
				}

				if(first_loc < last_loc){ //途中の数式を積む

					work = 0;

					work_num.push(0);
					work_op.push(buf[first_loc]);

					if(buf[first_loc] == '-'){


					}

					for(int i = first_loc+1; i < last_loc; i++){

						if(buf[i] == '*' || buf[i] == '+' || buf[i] == '-'){

							if(work_op.empty() == false && work_op.top() == '*'){

								work *= work_num.top();
								work %= MOD;
								work_num.pop();
								work_op.pop();
							}

							work_num.push(work);
							work_op.push(buf[i]);
							work = 0;

						}else{

							work = 10*work+(buf[i]-'0');
							work %= MOD;

							if(i+1 == last_loc){

								if(work_op.empty() == false && work_op.top() == '*'){

									work *= work_num.top();
									work %= MOD;
									work_num.pop();
									work_op.pop();
								}

								work_num.push(work);
							}
						}
					}

					//このままだと右結合になってしまうので左結合にする
					while(!work_num.empty()){

						calc_num.push(work_num.top());
						work_num.pop();
					}

					while(!work_op.empty()){

						calc_op.push(work_op.top());
						work_op.pop();
					}

					ll A;

					A = calc_num.top();
					calc_num.pop();

					while(!calc_op.empty()){
						if(calc_op.top() == '+'){

							A += calc_num.top();
							A %= MOD;

						}else{

							A -= calc_num.top();
							if(A < 0)A += MOD;
						}
						calc_op.pop();
						calc_num.pop();
					}

					NUM.push(A);
				}

				if(first_loc < last_loc){

					OP.push(buf[last_loc]);
				}

				if(last_loc == length-1){

					last_num = 0; //次の文字列と結合することはない
					is_last_num = false;

				}else{ //last_numを求める★★次に数字が連結する場合あり★★

					work = 0;

					//★★*が混ざっているか調べる★★
					int last_mult = -1;
					for(int i = length -1; i > last_loc; i--){

						if(buf[i] == '*'){

							last_mult = i;
							break;
						}
					}

					if(last_mult == -1 || last_mult < last_loc){ //最後の±から末尾までに*がない

						last_num = 0;

						for(int i = last_loc+1; i < length; i++){

							last_num = 10*last_num+(buf[i]-'0');
							last_num %= MOD;
						}

						if(last_loc == length-1){

							is_last_num = false;
						}else{

							is_last_num = true;
						}

					}else{ //last_loc+1～last_multまでをMULTに突っ込む

						work = 0;
						last_op = '*';

						for(int i = last_loc+1; i < last_mult; i++){

							if(buf[i] == '*'){

								work_num.push(work);
								work = 0;

							}else{

								work = 10*work+(buf[i]-'0');
								work %= MOD;

								if(i+1 == last_mult){

									work_num.push(work);
								}
							}
						}

						ll tmp = 1;

						while(!work_num.empty()){

							tmp *= work_num.top();
							tmp %= MOD;
							work_num.pop();
						}

						MULT.push(tmp);
						last_num = 0;

						for(int i = last_mult+1; i < length; i++){

							last_num = 10*last_num+(buf[i]-'0');
							last_num %= MOD;
						}

						if(last_mult == length-1){

							is_last_num = false;
						}else{

							is_last_num = true;
						}
					}
				}
			}
		}
	}

	//last_numが残っていたら処理
	if(last_op == '*'){

		while(!MULT.empty()){
			last_num *= MULT.front();
			last_num %= MOD;
			MULT.pop();
		}
		NUM.push(last_num);

	}else{

		NUM.push(last_num);
	}

	ll ans = NUM.front();
	NUM.pop();

	while(!OP.empty()){

		if(OP.front() == '+'){

			ans += NUM.front();
			ans %= MOD;
			NUM.pop();

		}else{

			ans -= NUM.front();
			if(ans < 0)ans += MOD;
			ans %= MOD;
			NUM.pop();
		}
		OP.pop();
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3440
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007LL

typedef vector<ll> vec;
typedef vector<vec> mat;

mat operator*(const mat& a,const mat& b){
  mat res(4,vec(4,0));
  const ll modl=8*mod*mod;
  rep(i,4){
    rep(k,4){
      rep(j,4){
        res[i][j]+=a[i][k]*b[k][j];
        if(res[i][j]>=modl)res[i][j]-=modl;
      }
    }
    rep(j,4)res[i][j]%=mod;
  }
  return res;
}

mat mpow(mat a,ll n){
  mat res(4,vec(4,0));
  rep(i,4)res[i][i]=1;
  while(n>0){
    if(n&1)res=res*a;
    a=a*a;
    n>>=1;
  }
  return res;
}

ll pls[4][4]={
  {1, 0, 1, 0},
  {0, 0, 0, 1},
  {0, 0, 0, 0},
  {0, 0, 0, 1},
};

ll mns[4][4]={
  {1, 0, 1, 0},
  {0, 0, 0, mod-1},
  {0, 0, 0, 0},
  {0, 0, 0, 1},
};

ll mul[4][4]={
  {1, 0, 0, 0},
  {0, 0, 1, 0},
  {0, 0, 0, 0},
  {0, 0, 0, 1},
};

ll num[4][4]={
  {1, 0, 0, 0},
  {0, 1, 0, 0},
  {0, 0, 10, 0},
  {0, 0, 0, 1},
};

int N;

int main(){
  scanf("%d",&N);
  vector<int> ps(N);
  vector<string> rs(N);
  rep(i,N){
    cin>>ps[i]>>rs[i];
  }
  ps.push_back(1); rs.push_back("+"); N++;
  mat crt(4,vec(4,0));
  rep(i,4)crt[i][i]=1;

  rep(i,N){
    mat m(4,vec(4,0));
    rep(j,4)m[j][j]=1;
    rep(j,rs[i].size()){
      mat op(4,vec(4,0));
      if(rs[i][j]=='+'){
        rep(k,4)rep(l,4)op[k][l]=pls[k][l];
      }
      if(rs[i][j]=='-'){
        rep(k,4)rep(l,4)op[k][l]=mns[k][l];
      }
      if(rs[i][j]=='*'){
        rep(k,4)rep(l,4)op[k][l]=mul[k][l];
      }
      if(isdigit(rs[i][j])){
        rep(k,4)rep(l,4)op[k][l]=num[k][l];
        op[2][1]=rs[i][j]-'0';
      }
      m=op*m;
    }
    m=mpow(m,ps[i]);
    crt=m*crt;
  }

  cout<<(crt[0][1]+crt[0][3])%mod<<endl;
  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3952
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;

typedef vector<ll> vec;
typedef vector<vec> mat;

mat mul(mat &A,mat &B){
	mat C(A.size(),vec(B[0].size()));
	for(int i=0;i<A.size();i++){
		for(int k=0;k<B.size();k++){
			for(int j=0;j<B[0].size();j++){
				C[i][j]=(C[i][j]+(A[i][k]*B[k][j]%MOD))%MOD;
			}
		}
	}
	return C;
}

mat pow(mat A,ll n){
	mat B(A.size(),vec(A.size()));
	for(int i=0;i<A.size();i++){
		B[i][i]=1;
	}
	while(n>0){
		if(n&1)B=mul(B,A);
		A=mul(A,A);
		n>>=1;
	}
	return B;
}

ll matpow(ll x,ll n){
	ll ret=1;
	while(n>0){
		if(n&1)ret=ret*x%MOD;
		x=x*x%MOD;
		n/=2LL;
	}
	return ret;
}

bool isnumber(string s){
	for(int i=0;i<s.size();i++){
		if(!isdigit(s[i]))return false;
	}
	return true;
}

ll getnum(string s){
	ll res=0;
	for(int i=0;i<s.size();i++){
		res*=10LL;
		res+=(s[i]-'0');
		res%=MOD;
	}
	return res;
}

typedef string::const_iterator State;
ll number(State &begin){
	ll ret=0;
	while(isdigit(*begin)){
		ret*=10;
		ret+=(*begin-'0');
		begin++;
	}
	ret%=MOD;
	return ret;
}

ll term(State &begin){
	ll ret=number(begin);
	while(1){
		if(*begin=='*'){
			begin++;
			ret*=number(begin);
			ret%=MOD;
		}else{
			break;
		}
	}
	return ret;
}
ll expression(State &begin){
	ll ret=term(begin);
	while(1){
		if(*begin=='+'){
			begin++;
			ret+=term(begin);
			ret%=MOD;
		}else{
			break;
		}
	}
	return ret;
}

ll getval(string s,int f){
	string ss=s.substr(f);
	if(f!=0)ss+=s.substr(0,f-1);
	else{
		ss=s.substr(0,s.size()-1);
	}
	State st=ss.begin();
	return expression(st);
}

string replace_str(string s){
	string res="";
	for(int i=0;i<s.size();i++){
		if(s[i]=='-'){
			res+="+1000000006*";
		}else{
			res+=s[i];
		}
	}
	return res;
}

int n;
int r[10005];
ll tp[15];

int main(void){
	scanf("%d%*c",&n);
	tp[0]=1;
	for(int i=0;i<14;i++){
		tp[i+1]=tp[i]*10LL%MOD;
	}
	ll ans=0;
	ll pv=1;
	ll nowv=0;
	for(int i=0;i<n;i++){
		string s;
		cin >> r[i] >> s;
		ll val=0;
		if(isnumber(s)){
			mat A(2,vec(2));
			A={{tp[s.size()],getnum(s)},{0,1}};
			A=pow(A,r[i]);
			nowv=((nowv*A[0][0])%MOD+A[0][1])%MOD;
			continue;
		}
		bool flag=false;
		for(int j=0;j<s.size();j++){
			if(s[j]=='+' || s[j]=='-'){
				flag=true;
			}
		}
		if(!flag){
			int mi=0;
			for(mi=0;mi<s.size();mi++){
				if(s[mi]=='*' || s[mi]=='+' || s[mi]=='-')break;
			}
			for(int j=0;j<mi;j++){
				nowv*=10LL;
				nowv+=(s[j]-'0');
				nowv%=MOD;
			}
			pv=nowv*pv%MOD;
			if(r[i]>1){
				nowv=getval(s,(mi+1)%s.size());
				nowv=matpow(nowv,r[i]-1);
				pv=nowv*pv%MOD;
			}
			nowv=0;
			for(int j=mi+1;j<s.size();j++){
				if(s[j]=='*'){
					pv=pv*nowv%MOD;
					nowv=0;
				}else{
					nowv*=10LL;
					nowv+=(s[j]-'0');
					nowv%=MOD;
				}
			}
		}else{
			s=replace_str(s);
			int mi=0;
			for(mi=0;mi<s.size();mi++){
				if(s[mi]=='+')break;
			}
			for(int j=0;j<mi;j++){
				if(s[j]=='*'){
					pv=pv*nowv%MOD;
					nowv=0;
				}else{
					nowv*=10LL;
					nowv+=s[j]-'0';
					nowv%=MOD;
				}
			}
			ans+=nowv*pv%MOD;
			ans%=MOD;
			if(r[i]>1){
				nowv=getval(s,(mi+1)%s.size());
				nowv*=r[i]-1;
				ans+=nowv%MOD;
				ans%=MOD;
			}
			pv=1;
			nowv=0;
			for(int j=mi+1;j<s.size();j++){
				if(s[j]=='*'){
					pv=pv*nowv%MOD;
					nowv=0;
				}else if(s[j]=='+'){
					ans+=nowv*pv%MOD;
					ans%=MOD;
					pv=1;
					nowv=0;
				}else{
					nowv*=10LL;
					nowv+=s[j]-'0';
					nowv%=MOD;
				}
			}
		}
	}
	ans+=nowv*pv%MOD;
	ans%=MOD;
	printf("%lld\n",ans);
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3360
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD = 1e9 + 7;
struct dt
{
	LL v, ev;
	dt(LL v = 0, LL ev = 0) : v(v % MOD), ev(ev % MOD) {}
	dt followed(const dt &o) const
	{
		dt ret;
		ret.v = (v * o.ev % MOD + o.v) % MOD;
		ret.ev = ev * o.ev % MOD;
		return ret;
	}
};
LL modExp(LL x, LL y)
{
	if (y == 0) return 1;
	if (y == 1) return x % MOD;
	LL ret = modExp(x, y / 2);
	ret = ret * ret % MOD;
	if (y & 1) ret = ret * x % MOD;
	return ret;
}
dt connect(dt x, LL y)
{
	if (y == 0) return dt(0, 1);
	if (y == 1) return dt(x.v % MOD, x.ev % MOD);
	dt ret = connect(x, y / 2);
	ret = ret.followed(ret);
	if (y % 2) ret = ret.followed(x);
	return ret;
}
typedef vector<dt> EXP;
LL calc(const EXP &e)
{
	EXP o;
	for (int i = 0; i < e.size(); ++i) {
		if (e[i].v == -3) {
			dt t = dt(o.back().v * e[i + 1].v % MOD);
			o.pop_back();
			o.push_back(t);
			++i;
		}
		else o.push_back(e[i]);
	}
	LL ret = o[0].v;
	for (int i = 1; i < o.size(); i += 2) {
		if (o[i].v == -1) ret = (ret + o[i + 1].v) % MOD;
		else ret = (ret + MOD - o[i + 1].v) % MOD;
	}
	return ret;
}
EXP compress(char *s, int r)
{
	EXP se;
	LL v = -4, len;
	for (int i = 0; s[i]; ++i) {
		if (isdigit(s[i])) {
			if (v == -4) v = 0, len = 1;
			v *= 10, v += s[i] - '0';
			len *= 10;
			v %= MOD, len %= MOD;
		}
		else {
			if (v != -4) se.push_back(dt(v, len));
			v = -4;
			if (s[i] == '+') se.push_back(dt(-1));
			else if (s[i] == '-') se.push_back(dt(-2));
			else se.push_back(dt(-3));
		}
	}
	if (v != -4) se.push_back(dt(v, len));
	if (r == 1) return se;
	int p = -1;
	for (int i = 0; i < se.size(); ++i) {
		if (se[i].v >= 0) continue;
		if (p == -1) p = i;
		else if (se[p].v < se[i].v) p = i;
	}
	EXP ret;
	if (p == -1) {
		ret.push_back(connect(se[0], r));
		return ret;
	}
	EXP re;
	for (int i = p + 1; i < se.size() + p; ++i) {
		if (!re.empty()) {
			if (re.back().v >= 0 && se[i % se.size()].v >= 0) {
				dt t = re.back().followed(se[i % se.size()]);
				re.pop_back();
				re.push_back(t);
				continue;
			}
		}
		re.push_back(se[i % se.size()]);
	}
	if (se[p].v == -2) {
		for (int i = 0; i < re.size(); ++i) {
			if (re[i].v == -1) re[i].v = -2;
			else if (re[i].v == -2) re[i].v = -1;
		}
	}
	LL val = calc(re);
	if (se[p].v == -3) val = modExp(val, r - 1);
	else val = val * (r - 1) % MOD;
	for (int i = 0; i <= p; ++i) ret.push_back(se[i]);
	ret.push_back(dt(val));
	for (int i = p; i < se.size(); ++i) ret.push_back(se[i]);
	return ret;
}
int main()
{
	int n; EXP e;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		int r;
		char s[200];
		scanf("%d%s", &r, s);
		EXP se = compress(s, r);
		for (int i = 0; i < se.size(); ++i) {
			if (!e.empty()) {
				if (e.back().v >= 0 && se[i].v >= 0) {
					dt t = e.back().followed(se[i]);
					e.pop_back();
					e.push_back(t);
					continue;
				}
			}
			e.push_back(se[i]);
		}
	}
	printf("%lld\n", calc(e));
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5920
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9+7;

string origine;

int modExp(long long a, long long b, int p) {
	int ret = 1;
	for (a = (a%p+p)%p; b; b >>= 1, a = a*a%p) if (b&1) ret = ret*a%p;
	return ret;
}

bool isDig(char c) {
	return '0' <= c && c <= '9';
}

long long calcExp(string exp) {
	if (!exp.size()) return 0;
	int cur = 0;
	if (exp[0] == '-' || exp[0] == '+') cur++;
	long long ret = 0;
	while (cur < exp.size()) {
		int sig = 1;
		if (cur && exp[cur - 1] == '-') sig = -1;
		long long val = 1, now = 0;
		while (cur < exp.size()) {
			if (exp[cur] == '*') {
				val = val * now % MOD;
				now = 0;
			}
			if (isDig(exp[cur])) now = (now * 10 + exp[cur] - '0') % MOD;
			if (exp[cur] == '+' || exp[cur] == '-') {
				++cur;
				break;
			}
			++cur;
		}
		val = val * now % MOD;
		ret = (ret + val * sig) % MOD;
	}
	ret = (ret % MOD + MOD) % MOD;
	return ret;
}

string toStr(long long val) {
	string ret;
	if (!val) {
		ret.push_back('0');
		return ret;
	}
	int flg = 0;
	if (val < 0) flg = 1, val *= -1;
	while (val) {
		ret.push_back('0' + val % 10);
		val /= 10;
	}
	if (flg) ret.push_back('-');
	reverse(ret.begin(), ret.end());
	return ret;
}

long long getVal(string str) {
	long long ret = 0, pw = 1;
	while (str.size()) {
		ret = (ret + pw * (str.back() - '0')) % MOD;
		str.pop_back();
		pw = pw * 10 % MOD;
	}
	return ret;
}

string convert(string exp, int times) {
	if (times == 1) return exp;
	int sz = exp.size();
	int pos = -1;
	string head, tail;
	for (int i = 0; i < sz; i++) {
		if (exp[i] == '+' || exp[i] == '-') {
			pos = i;
			break;
		}
		head.push_back(exp[i]);
	}
	if (pos >= 0) {
		for (int i = pos; i < sz; i++) tail.push_back(exp[i]);
		long long val = calcExp(tail + head);
		val = (val * (times - 1)) % MOD;
		return head + "+" + toStr(val) + tail;
	}
	pos = -1;
	head.clear();
	for (int i = 0; i < sz; i++) {
		if (exp[i] == '*') {
			pos = i;
			break;
		}
		head.push_back(exp[i]);
	}
	if (pos >= 0) {
		for (int i = pos + 1; i < sz; i++) tail.push_back(exp[i]);
		long long val = calcExp(tail + head);
		val = modExp(val, (times - 1), MOD);
		return head + "*" + toStr(val) + "*" + tail;
	}
	string empty;
	return empty;
}

void append(string str, int times) {
	string res = convert(str, times);
	if (res.size()) {
		origine += res;
		return;
	}
	string tail;
	while (origine.size() && isDig(origine.back())) tail.push_back(origine.back()), origine.pop_back();
	reverse(tail.begin(), tail.end());
	long long head = getVal(tail);
	long long val = getVal(str);
	int l = str.size();
	long long inst = head * modExp(10, 1LL * l * times, MOD) % MOD + val * (modExp(10, 1LL * l * times, MOD) - 1) % MOD * modExp((modExp(10, 1LL * l, MOD) - 1) % MOD, MOD - 2, MOD) % MOD;
	inst = ((inst % MOD) + MOD) % MOD;
	origine += toStr(inst);
}

int main() {
	ios_base::sync_with_stdio(0);
	int n; cin >> n;
	while (n--) {
		int times; string tmp; 
		cin >> times >> tmp;
		append(tmp, times);
	}
	cout << calcExp(origine) << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3492
final_rank: 1

code_snippet: #include<bits/stdc++.h>

using namespace std;

typedef long long LL;

constexpr int N = 10001, MOD = 1e9+7;

int n, r;
char s[N];

struct Vec {
  LL a[4];
  Vec() { memset(a, 0, sizeof(a)); }
  LL& operator [] (const int &i) { return a[i]; }
  const LL& operator [] (const int &i) const { return a[i]; }
  void print() {
    for(int i = 0; i < 4; ++i)
      fprintf(stderr, "%lld%c", a[i], "\t\n"[i==3]);
  }
};
struct Mat {
  Vec a[4];
  Vec& operator [] (const int &i) { return a[i]; }
  const Vec& operator [] (const int &i) const { return a[i]; }
  Mat operator * (const Mat &b) {
    Mat rtn;
    for(int i = 0; i < 4; ++i)
      for(int j = 0; j < 4; ++j)
        for(int k = 0; k < 4; ++k)
          rtn[i][j] = (MOD + rtn[i][j] + a[i][k] * b[k][j]) % MOD;
    return rtn;
  }
  Vec operator * (const Vec &v) {
    Vec rtn;
    for(int i = 0; i < 4; ++i)
      for(int j = 0; j < 4; ++j)
        rtn[i] = (MOD + rtn[i] + a[i][j] * v[j]) % MOD;
    return rtn;
  }
  void print() {
    cerr << string(30, '-') << endl;
    for(int i = 0; i < 4; ++i)
      a[i].print();
  }
};

int main() {
  Mat eye, mul, pos, neg, dig;
  for(int i = 0; i < 4; ++i)
    eye[i][i] = 1;
  mul[0][0] = mul[1][2] = mul[3][3] = 1;
  pos[0][0] = pos[0][2] = pos[1][3] = pos[3][3] = 1;
  neg[0][0] = neg[0][2] = neg[3][3] = 1;
  neg[1][3] = -1;
  dig[0][0] = dig[1][1] = dig[3][3] = 1;
  dig[2][2] = 10;
  Vec v;
  v[1] = v[3] = 1;
  scanf("%d", &n);
  for(int i = 0; i < n; ++i) {
    scanf("%d %s", &r, s);
    Mat t = eye;
    for(int j = 0; s[j]; ++j) {
      if(s[j] == '*')
        t = mul * t;
      else if(s[j] == '+')
        t = pos * t;
      else if(s[j] == '-')
        t = neg * t;
      else {
        dig[2][1] = (s[j] - '0');
        t = dig * t;
      }
    }
    Mat cur = eye;
    while(r) {
      if(r & 1)
        cur = t * cur;
      r >>= 1;
      t = t * t;
    }
    v = cur * v;
  }
  printf("%lld\n", (MOD + v[0] + v[2]) % MOD);
}
accuracy: 1
time_ms: 70
memory_kb: 3208
final_rank: 9

code_snippet: #include <bits/stdc++.h>

const int MOD = 1E9 + 7;

const int NMAT[7][7] = {
	{1, 0, 0, 0, 0, 0, 0},
	{0, 1, 0, 0, 0, 0, 0},
	{0, 0, 1, -1, 0, 0, 0},
	{0, 0, 0, 10, 0, 0, 0},
	{0, 0, 0, 0, 1, -1, 0},
	{0, 0, 0, 0, 0, 10, 0},
	{0, 0, 0, 0, 0, 0, 1}
};

const int MMAT[7][7] = {
	{1, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 1, 0, 0},
	{0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 1, 0, 0},
	{0, 0, 0, 0, 0, 0, 1},
};

const int AMAT[7][7] = {
	{1, 0, 0, 0, -1, 0, 0},
	{0, 0, 0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 1},
	{0, 0, 0, 0, 0, 0, 1}
};

struct mat {
	int d[7][7];
	mat () { for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) d[i][j] = 0; }
	int *operator [] (int x) { return d[x]; }
	int const *operator [] (int x) const { return d[x]; }
};

mat operator * (const mat &a, const mat &b) {
	mat res;
	for (int i = 0; i < 7; ++i)
		for (int j = 0; j < 7; ++j)
			for (int k = 0; k < 7; ++k)
				res[i][j] = (res[i][j] + 1ll * a[i][k] * b[k][j]) % MOD;
	return res;
}

mat id () {
	mat res;
	for (int i = 0; i < 7; ++i)
		res[i][i] = 1;
	return res;
}

mat nmat[10], mmat, amat, smat;

void init () {
	for (int digit = 0; digit < 10; ++digit)
		for (int i = 0; i < 7; ++i)
			for (int j = 0; j < 7; ++j)
				nmat[digit][i][j] = (NMAT[i][j] < 0) ? digit : NMAT[i][j];
	for (int i = 0; i < 7; ++i)
		for (int j = 0; j < 7; ++j)
			mmat[i][j] = MMAT[i][j];
	for (int i = 0; i < 7; ++i)
		for (int j = 0; j < 7; ++j)
			amat[i][j] = (AMAT[i][j] < 0) ? 1 : AMAT[i][j];
	for (int i = 0; i < 7; ++i)
		for (int j = 0; j < 7; ++j)
			smat[i][j] = (AMAT[i][j] < 0) ? MOD - 1 : AMAT[i][j];
}

int N;
int R[11000];
char S[11000][20];

int ans[7] = {0, 1, 0, 1, 0, 1, 1}, tmp[7];

int main () {
	init ();
	scanf ("%d", &N);
	for (int i = 0; i < N; ++i)
		scanf ("%d %s", &R[i], S[i]);
	for (int i = N - 1; i >= 0; --i) {
		mat mul = id (), ter = id ();
		for (int j = strlen (S[i]) - 1; j >= 0; --j) {
			if (S[i][j] >= '0' && S[i][j] <= '9') mul = nmat[S[i][j] - '0'] * mul;
			else if (S[i][j] == '*') mul = mmat * mul;
			else if (S[i][j] == '+') mul = amat * mul;
			else mul = smat * mul;
		}
		while (R[i]) {
			if (R[i] & 1) ter = mul * ter;
			mul = mul * mul;
			R[i] >>= 1;
		}
		for (int i = 0; i < 7; ++i) {
			tmp[i] = 0;
			for (int j = 0; j < 7; ++j)
				tmp[i] = (tmp[i] + 1ll * ans[j] * ter[i][j]) % MOD;
		}
		for (int i = 0; i < 7; ++i) ans[i] = tmp[i];
	}
	for (int i = 0; i < 7; ++i) {
		tmp[i] = 0;
		for (int j = 0; j < 7; ++j)
			tmp[i] = (tmp[i] + 1ll * ans[j] * amat[i][j]) % MOD;
	}
	for (int i = 0; i < 7; ++i) ans[i] = tmp[i];
	printf ("%d\n", ans[0]);
}
accuracy: 1
time_ms: 450
memory_kb: 3452
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;

const ll mod = 1e9+7;

ll mod_pow(ll x, ll p){
  ll res = 1;

  while(p){
    if(p&1LL) res = res * x % mod;
    x = x * x % mod;
    p >>= 1;
  }

  return res;
}

mat mat_prod(mat A, mat B){
  size_t h = A.size(), w = B.size();
  mat res(h, vec(w,0));
  for(size_t i=0;i<h;i++){
    for(size_t j=0;j<w;j++){
      for(size_t k=0;k<A[i].size();k++){
	res[i][j] += A[i][k] * B[k][j] % mod;
	res[i][j] %= mod;
      }
    }
  }
  return res;
}	  

mat mat_pow(mat A, ll p){
  int n = A.size();
  mat res(n, vec(n,0));
  for(int i=0;i<n;i++) res[i][i] = 1;

  while(p){
    if(p&1LL) res = mat_prod(res, A);
    A = mat_prod(A,A);
    p >>= 1;
  }

  return res;
}

inline ll calc(const string s, ll &prod, ll &rem){
  ll res = 0;
  for(char c : s){
    if(c == '*'){
      prod *= rem;
      prod %= mod;
      rem = 0;
    }else if(c == '+'){
      res += (prod * rem) % mod;
      res %= mod;
      prod = 1; rem = 0;
    }else if(c == '-'){
      res += (prod * rem) % mod;
      res %= mod;
      prod = mod-1; rem = 0;
    }else{
      rem = rem*10 + (ll)(c-'0');
      rem %= mod;
    }
  }

  return res;
}

int main(){
  ll n;
  cin >> n;

  //temporary result can be represented as "add + prod * rem"
  ll add=0, prod=1, rem=0;

  //tuple<ll,ll> : <times, add before par, prod before par>
  stack< tuple<ll,ll,ll> > open;

  while(n--){
    ll r; string s;
    cin >> r >> s;

    if(s.find("(") != string::npos){
      size_t p = s.find("(");
      string pre = s.substr(0,p), suf = s.substr(p+1);
      add += calc(pre, prod, rem) % mod;
      add %= mod;
      
      open.push( make_tuple(1LL, add, prod) );
      add = 0, prod = 1;

      if(r-1>0){
	add += calc(suf + pre, prod, rem) % mod;
	add %= mod;
	
	open.push( make_tuple(r-1, add, prod) );
	add = 0, prod = 1;
      }

      add += calc(suf, prod, rem) % mod;
      add %= mod;
    }else if(s.find(")") != string::npos){
      size_t p = s.find(")");
      string pre = s.substr(0,p), suf = s.substr(p+1);

      add += calc(pre, prod, rem) % mod;
      add %= mod;

      ll x = (add + (prod*rem%mod)) % mod, t;

      if(r-1>0){
	r--;
	string m = suf + pre;
	size_t k = 0;
	ll cp = 1;
	while(k<m.size() && m[k] == '*'){
	  ll tmp = 0;
	  k++;
	  while(k<m.size() && isdigit(m[k])){
	    tmp = tmp*10 + (ll)(m[k]-'0');
	    tmp %= mod;
	    k++;
	  }
	  cp *= tmp;
	}
	
	ll ca = 0, tp = 1, trem = 0;
	ca += calc(m.substr(k), tp, trem) % mod;
	ca %= mod;
	
	ca = (ca + (tp*trem%mod)) % mod;
	
	while(r){
	  assert( !open.empty() );
	  ll oa,op;
	  tie(t,oa,op) = open.top(); open.pop();
	  
	  if(t > r) open.push( make_tuple(t-r, oa, op) );
	  
	  t = min(t, r);
	  r -= t;
	  
	  //calc f^t(x), where f(x) = cp*op*x + ca+oa
	  (op *= cp) %= mod;
	  (oa += ca) %= mod;
	  
	  mat A = { {op, oa}, {0,1} };
	  A = mat_pow(A, t);
	  x = A[0][0] * x + A[0][1];
	  x %= mod;
	}      	
      }

      tie(t,add,prod) = open.top(); open.pop();
      if(t-1>0) open.push( make_tuple(t-1, add, prod) );
      rem = x;
      
      add += calc(suf, prod, rem) % mod;
      add %= mod;
    }else if(s.find("+") != string::npos || s.find("-") != string::npos ){
      size_t p = min( s.find("+"), s.find("-") );
      string pre = s.substr(0,p+1), suf = s.substr(p+1);
      add += calc(pre, prod, rem) % mod;
      add %= mod;

      add += (r-1) * calc(suf + pre, prod, rem) % mod;
      add %= mod;

      add += calc(suf, prod, rem) % mod;
      add %= mod;
    }else if(s.find("*") != string::npos){
      size_t p = s.find("*");
      string pre = s.substr(0,p+1), suf = s.substr(p+1);
      calc(pre, prod, rem);
 
      ll x = 1;
      calc(suf + pre, x, rem);
      prod *= mod_pow(x, r-1);
      prod %= mod;
      
      calc(suf, prod, rem);
    }else{
      ll x = 0, dummy = 1;
      calc(s, dummy, x);

      mat A = { {mod_pow(10, s.size()), x}, {0,1} };
      A = mat_pow(A, r);
      rem = A[0][0] * rem + A[0][1];
      rem %= mod;
    }
  }

  assert(open.empty());

  add += calc("+0", prod, rem) % mod;
  add %= mod;
  cout << add << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3232
final_rank: 4

code_snippet: /**************************************************************************************************************
   *  Md. Abdulla Al Mamun (Nayon)
   *  ID: 1306001
   *  Session: 2013-2014
   *  Department of Computer Science and Engineering
   *  Begum Rokeya University, Rangpur (BRUR)
***************************************************************************************************************/
#include <bits/stdc++.h>
using namespace std;

#define PI acos(-1.0)
#define EPS 1e-9
#define INF 1 << 28
#define sq(a) ((a) * (a))
#define toRad(a) ((a)*(PI)/180)
#define toDeg(a) ((a)*180/(PI))
#define all(x) (x).begin(), (x).end()
#define pb(x) push_back(x)
#define mp(a, b) make_pair((a), (b))
#define endl '\n'
#define MAX 100000
#define MOD 1000000007
#define what_is(x) cerr << #x << " is " << x << endl;
#define mset(array, value) memset(array, value, sizeof(array))

inline bool isEq(double a, double b){return (abs(a-b) < EPS);}

typedef long long ll;
typedef pair<int, int> pii;
inline ll negModHandler(ll a, ll d){return ((a%d)<0)?d+(a%d):(a%d);}

//#define isValid(a, b) ((a >= 0 && a < b) ? 1 : 0)
//int dr[]  =  {0, -1, -1, -1,  0,  1, 1, 1};
//int dc[]  =  {1,  1,  0, -1, -1, -1, 0, 1};

string strMod(string s)
{
	ll n = 0, len = s.length();
	for(int i = 0; i < len; i++){
		n = (n*10 + s[i]-'0')%MOD;
	}
	stringstream ss;
	ss << n;
	ss >> s;
	return s;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	int n, r, i;
	string str, all;
	stringstream ss, ss2;
	cin >> n;
	all = "";
	while(n--){
		cin >> r >> str;
		for(i = 0; i < r; i++){
			all += str;
		}
	}
	//cout << "# " << all << endl;
	int ln = all.length();
	string all2 = "";
	str = "";
	for(i = 0; i < ln; i++){
		while(i < ln && isdigit(all[i])){
			str += all[i];
			i++;
		}
		while(i < ln && all[i] == '*'){
			string str2 = "";
			i++;
			while(isdigit(all[i])){
				str2 += all[i];
				i++;
			}
			ss.clear();
			ss2.clear();
			ss << strMod(str);
			ss2 << strMod(str2);
			ll n1, n2;
			ss >> n1;
			ss2 >> n2;
			n1 = (n1 %MOD * n2%MOD)%MOD;
			ss.clear();
			ss << n1;
			ss >> str;
		}
		if(all[i] == '-' || all[i] == '+'){
			str+=all[i];
		}
		all2 += str;
		str = "";
	}
	//cout << "# " << all2 << endl;
	ln = all2.length();
	ll ans = 0;
	str = "";
	i = 0;
	while(i < ln && isdigit(all2[i])){
		str += all2[i];
		i++;
	}
	ss.clear();
	ss << strMod(str);
	ss >> ans;
	if(i < ln){
		char sign = all2[i];
		for(i++; i < ln; i++){
			str = "";
			while(i < ln && isdigit(all2[i])){
				str += all2[i];
				i++;
			}
			ll n1;
			ss.clear();
			ss << strMod(str);
			ss >> n1;
			if(sign == '+'){
				ans = negModHandler(ans+n1, MOD);
			}
			else{
				ans = negModHandler(ans-n1, MOD);
			}
			if(i < ln)
				sign = all2[i];
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 0.3877551020408163
time_ms: 30
memory_kb: 3776
final_rank: 19