Problem p03114 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define mod 1000000007
#define i9 111111112
#define i10 700000005
typedef long long ll;
ll gi() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch))
    f ^= ch == '-', ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  return f ? x : -x;
}
int pow(int x, int y) {
  int ret = 1;
  while (y) {
    if (y & 1)
      ret = 1ll * ret * x % mod;
    x = 1ll * x * x % mod;
    y >>= 1;
  }
  return ret;
}
int pl[21], pr[21], p[33], m, dp[10][32769], s0[31], s1[31];
void add(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
int _S[32769], _X[32769];
int main() {
#ifdef XZZSB
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif
  int n = gi() + 2, q = gi();
  for (int i = 1; i <= q; ++i)
    p[++m] = pl[i] = gi(), p[++m] = pr[i] = gi() + 1;
  std::sort(p + 1, p + m + 1);
  m = std::unique(p + 1, p + m + 1) - p - 1;
  for (int i = 1; i <= q; ++i)
    pl[i] = std::lower_bound(p + 1, p + m + 1, pl[i]) - p;
  for (int i = 1; i <= q; ++i)
    pr[i] = std::lower_bound(p + 1, p + m + 1, pr[i]) - p;
  for (int i = 1; i <= m; ++i)
    s1[i] = 1ll * (pow(10, p[i] - p[i - 1]) - 1) * i9 % mod;
  for (int i = 1; i <= m; ++i)
    s0[i] = 1ll * (1ll * (pow(10, p[i] - p[i - 1]) - 1) * i9 + 1) % mod *
            pow(s1[i], mod - 2) % mod;
  dp[0][0] = 1;
  for (int T = 0; T < 1 << q; ++T) {
    for (int k = 1; k <= q; ++k)
      if (T >> k - 1 & 1)
        _S[T] |= (1 << pl[k] - 1) | (1 << pr[k] - 1);
    _X[T] = 1;
    for (int k = 2; k <= m; ++k)
      if ((_S[T] >> k - 1 & 1) && (_S[T] >> k - 2 & 1))
        _X[T] = 1ll * _X[T] * s0[k] % mod;
  }
  for (int i = 0; i < 9; ++i)
    for (int j = 0; j < 1 << q; ++j) {
      if (!dp[i][j])
        continue;
      int S = 0;
      for (int k = 1; k <= q; ++k)
        if (j >> k - 1 & 1)
          S |= (1 << pl[k] - 1) | (1 << pr[k] - 1);
      for (int k = 1; k <= q; ++k)
        if ((S >> pl[k] - 1 & 1) ^ (S >> pr[k] - 1 & 1)) {
          S = -1;
          break;
        }
      for (int k = 1; k <= q; ++k)
        if (((~j >> k - 1) & 1) && (S >> pl[k] - 1 & 1)) {
          S = -1;
          break;
        }
      if (S == -1) {
        dp[i][j] = 0;
        continue;
      }
      int U = ((1 << q) - 1) ^ j;
      for (int T = U;; T = (T - 1) & U) {
        S = _S[T];
        int x = 1ll * dp[i][j] * _X[T] % mod;
        if ((S & 1) && (i == 0))
          x = 1ll * x * s0[1] % mod;
        add(dp[i + 1][j | T], x);
        if (!T)
          break;
      }
    }
  int ans = 1ll * dp[9][(1 << q) - 1] * pow(10, n - p[m]) % mod;
  for (int i = 1; i <= m; ++i)
    ans = 1ll * ans * s1[i] % mod;
  printf("%d\\n", 1ll * ans * i10 % mod * i10 % mod);
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define mod 1000000007
#define i9 111111112
#define i10 700000005
typedef long long ll;
ll gi() {
  ll x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch))
    f ^= ch == '-', ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  return f ? x : -x;
}
int pow(int x, int y) {
  int ret = 1;
  while (y) {
    if (y & 1)
      ret = 1ll * ret * x % mod;
    x = 1ll * x * x % mod;
    y >>= 1;
  }
  return ret;
}
int pl[21], pr[21], p[33], m, dp[10][32769], s0[31], s1[31];
void add(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
int main() {
#ifdef XZZSB
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif
  int n = gi() + 2, q = gi();
  for (int i = 1; i <= q; ++i)
    p[++m] = pl[i] = gi(), p[++m] = pr[i] = gi() + 1;
  std::sort(p + 1, p + m + 1);
  m = std::unique(p + 1, p + m + 1) - p - 1;
  for (int i = 1; i <= q; ++i)
    pl[i] = std::lower_bound(p + 1, p + m + 1, pl[i]) - p;
  for (int i = 1; i <= q; ++i)
    pr[i] = std::lower_bound(p + 1, p + m + 1, pr[i]) - p;
  for (int i = 1; i <= m; ++i)
    s1[i] = 1ll * (pow(10, p[i] - p[i - 1]) - 1) * i9 % mod;
  for (int i = 1; i <= m; ++i)
    s0[i] = 1ll * (1ll * (pow(10, p[i] - p[i - 1]) - 1) * i9 + 1) % mod *
            pow(s1[i], mod - 2) % mod;
  dp[0][0] = 1;
  for (int i = 0; i < 9; ++i)
    for (int j = 0; j < 1 << q; ++j) {
      if (!dp[i][j])
        continue;
      int S = 0;
      for (int k = 1; k <= q; ++k)
        if (j >> k - 1 & 1)
          S |= (1 << pl[k] - 1) | (1 << pr[k] - 1);
      for (int k = 1; k <= q; ++k)
        if ((S >> pl[k] - 1 & 1) ^ (S >> pr[k] - 1 & 1)) {
          S = -1;
          break;
        }
      for (int k = 1; k <= q; ++k)
        if (((~j >> k - 1) & 1) && (S >> pl[k] - 1 & 1)) {
          S = -1;
          break;
        }
      if (S == -1) {
        dp[i][j] = 0;
        continue;
      }
      int U = ((1 << q) - 1) ^ j;
      for (int T = U;; T = (T - 1) & U) {
        S = 0;
        for (int k = 1; k <= q; ++k)
          if (T >> k - 1 & 1)
            S |= (1 << pl[k] - 1) | (1 << pr[k] - 1);
        int x = dp[i][j];
        for (int k = 1; k <= m; ++k)
          if ((S >> k - 1 & 1) && (k == 1 ? i == 0 : (S >> k - 2 & 1)))
            x = 1ll * x * s0[k] % mod;
        add(dp[i + 1][j | T], x);
        if (!T)
          break;
      }
    }
  int ans = 1ll * dp[9][(1 << q) - 1] * pow(10, n - p[m]) % mod;
  for (int i = 1; i <= m; ++i)
    ans = 1ll * ans * s1[i] % mod;
  printf("%d\\n", 1ll * ans * i10 % mod * i10 % mod);
  return 0;
}