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

#include <bits/stdc++.h>
#define BM (1 << 12)
#define BT (1 << 19)
#define MOD 1000000007
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

ll memo[BM][BM];
int A[BT], B[BT];

ll score(int s, int t) {
  if (s == t)
    return s + 1;
  return score((s - 1) / 2, (t - 1) / 2) * (ll)(s + 1) % MOD * (ll)(t + 1) %
         MOD;
}
int main() {
  int n;
  scanf("%d", &n);
  n--;
  int b = min(6, n), block = 1 << b;
  // b=2,block=1<<b;
  for (int i = 0; i < 1 << n; i++) {
    scanf("%d", &A[i]);
    A[i]--;
    // A[i]=i;
    B[A[i]] = i;

    int a = i + (1 << n) - 1, a2 = A[i] + (1 << n) - 1;
    vector<int> vx, vy;
    vector<ll> vs, vt;
    ll now = 1;
    while (1) {
      now *= a + 1;
      now %= MOD;
      if (a < (1 << (n - b + 1)) - 1) {
        vx.push_back(a);
        vs.push_back(now);
      }
      if (a == 0)
        break;
      a = (a - 1) / 2;
    }
    now = 1;
    a = a2;
    while (1) {
      now *= a + 1;
      now %= MOD;
      if (a < (1 << (n - b + 1)) - 1) {
        vy.push_back(a);
        vt.push_back(now);
      }
      if (a == 0)
        break;
      a = (a - 1) / 2;
    }
    for (int i = 0; i < vx.size(); i++) {
      for (int j = 0; j < vy.size(); j++) {
        memo[vx[i]][vy[j]] += vs[i] * vt[j] % MOD;
        if (memo[vx[i]][vy[j]] >= MOD)
          memo[vx[i]][vy[j]] -= MOD;
      }
    }
  } /*
   for(int i=0;i<1<<n ;i++)
   {
           for(int j=0;j<1<<n;j++) printf("%lld ",memo[i][j]);
           puts("");
   }*/
  ll ret = 0, ret2 = 0;
  for (int i = 0; i < 1 << n; i++) {
    int r = i / block;
    int r2 = A[i] / block;
    for (int j = i % block + 1; j < block; j++) {
      int v = r * block + j;
      if (A[v] / block != r2) {
        ret += score((1 << n) - 1 + i, (1 << n) - 1 + v) *
               score((1 << n) - 1 + A[i], (1 << n) - 1 + A[v]) % MOD;
        if (ret >= MOD)
          ret -= MOD;
      }
    }
    for (int j = A[i] % block + 1; j < block; j++) {
      int v = B[r2 * block + j];
      ret += score((1 << n) - 1 + i, (1 << n) - 1 + v) *
             score((1 << n) - 1 + A[i], (1 << n) - 1 + A[v]) % MOD;
      if (ret >= MOD)
        ret -= MOD;
    }

    if (b < n) {
      int a = i + (1 << n) - 1, a2 = A[i] + (1 << n) - 1;
      vector<int> vx, vy;
      vector<ll> vs, vt;
      ll now = 1;
      int bef = -1;
      while (1) {
        now *= a + 1;
        now %= MOD;
        if (a < (1 << (n - b)) - 1) {
          int to = 2 * a + 1;
          if (bef == to)
            to++;
          vx.push_back(to);
          vs.push_back(now);
        }
        if (a == 0)
          break;
        bef = a;
        a = (a - 1) / 2;
      }
      now = 1;
      bef = -1;
      a = a2;
      while (1) {
        now *= a + 1;
        now %= MOD;
        if (a < (1 << (n - b)) - 1) {
          int to = 2 * a + 1;
          if (bef == to)
            to++;
          vy.push_back(to);
          vt.push_back(now);
        }
        if (a == 0)
          break;
        bef = a;
        a = (a - 1) / 2;
      }
      for (int j = 0; j < vx.size(); j++) {
        for (int k = 0; k < vy.size(); k++) {
          // if(memo[vx[j]][vy[k]]!=0) printf("%d : %d %d\\n",i,vx[j],vy[k]);
          ret2 += vs[j] * vt[k] % MOD * memo[vx[j]][vy[k]] % MOD;
          if (ret2 >= MOD)
            ret2 -= MOD;
        }
      }
    }
  }
  if (ret2 % 2 == 1)
    ret2 += MOD;
  ret2 /= 2;
  printf("%lld\\n", (ret + ret2) % MOD);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define BM (1 << 11)
#define BT (1 << 19)
#define MOD 1000000007
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

ll memo[BM][BM];
int A[BT], B[BT];

ll score(int s, int t) {
  if (s == t)
    return s + 1;
  return score((s - 1) / 2, (t - 1) / 2) * (ll)(s + 1) % MOD * (ll)(t + 1) %
         MOD;
}
int main() {
  int n;
  scanf("%d", &n);
  n--;
  int b = min(7, n), block = 1 << b;
  // b=2,block=1<<b;
  for (int i = 0; i < 1 << n; i++) {
    scanf("%d", &A[i]);
    A[i]--;
    B[A[i]] = i;

    int a = i + (1 << n) - 1, a2 = A[i] + (1 << n) - 1;
    vector<int> vx, vy;
    vector<ll> vs, vt;
    ll now = 1;
    while (1) {
      now *= a + 1;
      now %= MOD;
      if (a < (1 << (n - b + 1)) - 1) {
        vx.push_back(a);
        vs.push_back(now);
      }
      if (a == 0)
        break;
      a = (a - 1) / 2;
    }
    now = 1;
    a = a2;
    while (1) {
      now *= a + 1;
      now %= MOD;
      if (a < (1 << (n - b + 1)) - 1) {
        vy.push_back(a);
        vt.push_back(now);
      }
      if (a == 0)
        break;
      a = (a - 1) / 2;
    }
    for (int i = 0; i < vx.size(); i++) {
      for (int j = 0; j < vy.size(); j++) {
        memo[vx[i]][vy[j]] += vs[i] * vt[j] % MOD;
        if (memo[vx[i]][vy[j]] >= MOD)
          memo[vx[i]][vy[j]] -= MOD;
      }
    }
  } /*
   for(int i=0;i<1<<n ;i++)
   {
           for(int j=0;j<1<<n;j++) printf("%lld ",memo[i][j]);
           puts("");
   }*/
  ll ret = 0, ret2 = 0;
  for (int i = 0; i < 1 << n; i++) {
    int r = i / block;
    int r2 = A[i] / block;
    for (int j = i % block + 1; j < block; j++) {
      int v = r * block + j;
      if (A[v] / block != r2) {
        ret += score((1 << n) - 1 + i, (1 << n) - 1 + v) *
               score((1 << n) - 1 + A[i], (1 << n) - 1 + A[v]) % MOD;
        if (ret >= MOD)
          ret -= MOD;
      }
    }
    for (int j = A[i] % block + 1; j < block; j++) {
      int v = B[r2 * block + j];
      ret += score((1 << n) - 1 + i, (1 << n) - 1 + v) *
             score((1 << n) - 1 + A[i], (1 << n) - 1 + A[v]) % MOD;
      if (ret >= MOD)
        ret -= MOD;
    }

    if (b < n) {
      int a = i + (1 << n) - 1, a2 = A[i] + (1 << n) - 1;
      vector<int> vx, vy;
      vector<ll> vs, vt;
      ll now = 1;
      int bef = -1;
      while (1) {
        now *= a + 1;
        now %= MOD;
        if (a < (1 << (n - b)) - 1) {
          int to = 2 * a + 1;
          if (bef == to)
            to++;
          vx.push_back(to);
          vs.push_back(now);
        }
        if (a == 0)
          break;
        bef = a;
        a = (a - 1) / 2;
      }
      now = 1;
      bef = -1;
      a = a2;
      while (1) {
        now *= a + 1;
        now %= MOD;
        if (a < (1 << (n - b)) - 1) {
          int to = 2 * a + 1;
          if (bef == to)
            to++;
          vy.push_back(to);
          vt.push_back(now);
        }
        if (a == 0)
          break;
        bef = a;
        a = (a - 1) / 2;
      }
      for (int j = 0; j < vx.size(); j++) {
        for (int k = 0; k < vy.size(); k++) {
          // if(memo[vx[j]][vy[k]]!=0) printf("%d : %d %d\\n",i,vx[j],vy[k]);
          ret2 += vs[j] * vt[k] % MOD * memo[vx[j]][vy[k]] % MOD;
          if (ret2 >= MOD)
            ret2 -= MOD;
        }
      }
    }
  }
  if (ret2 % 2 == 1)
    ret2 += MOD;
  ret2 /= 2;
  printf("%lld\\n", (ret + ret2) % MOD);
}