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

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = (1 << 18) + 100;
const ll MOD = 1e9 + 7;

ll cpow(ll b, int e) {
  if (e == 0)
    return 1;
  if (e == 1)
    return (b % MOD);
  ll v = cpow(b, e / 2);
  v = (v * v) % MOD;
  if (e % 2 == 1)
    v = (v * b) % MOD;
  return v;
}

ll inv(ll x) { return cpow(x, MOD - 2); }

ll mscore[MAXN];
ll iscore[MAXN];

int L, N;
int ncross[MAXN];
ll np[MAXN];

pair<ll, ll> ps[MAXN];

int main() {
  ios_base::sync_with_stdio(0);

  mscore[0] = 1;
  iscore[0] = 1;
  mscore[1] = 1;
  for (int i = 2; i < (1 << 18); i++) {
    mscore[i] = (i * mscore[i / 2]) % MOD;
  }
  for (int i = 1; i < (1 << 18); i++)
    iscore[i] = inv((mscore[i] * mscore[i / 2]) % MOD);

  cin >> L;
  N = (1 << (L - 1));
  for (int i = 0; i < N; i++) {
    cin >> ncross[i];
    ncross[i]--;
    np[i] = (mscore[i + N] * mscore[ncross[i] + N]) % MOD;
  }

  ll ans = 0;
  for (int i = 0; i < L - 1; i++)
    for (int j = 0; j < L - 1; j++) {
      unordered_map<int, pair<ll, ll>> mm;
      for (int k = 0; k < N; k++) {
        int v = ncross[k] >> (L - 1 - j);
        int b1 = (k >> (L - 2 - i) & 1);
        int b2 = (ncross[k] >> (L - 2 - j)) & 1;
        v = 2 * v + (b1 ^ b2);
        if (b2)
          mm[v].second += np[k];
        else
          mm[v].first += np[k];

        if ((k + 1) % (1 << (L - 1 - i)) == 0) {
          for (auto it = mm.begin(); it != mm.end(); it++) {
            if (!it->second.first || !it->second.second)
              continue;
            ll l = it->second.first % MOD, l2 = it->second.second % MOD;
            // cout << i << " " << j << " " << l << " " << l2 << "\\n";

            ll v = (l * l2) % MOD;
            ll mask = it->first;
            int a1 = (1 << i) + (k >> (L - 1 - i));
            int a2 = (1 << j) + (mask / 2) % (1 << j);
            // cout << mask << " " << a1 << " " << a2 << "\\n";
            v = v * (iscore[a1]) % MOD;
            v = v * (iscore[a2]) % MOD;
            ans += v;
          }
          mm.clear();
        }
      }
    }
  ans %= MOD;
  cout << ans << "\\n";
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = (1 << 18) + 100;
const ll MOD = 1e9 + 7;

ll cpow(ll b, int e) {
  if (e == 0)
    return 1;
  if (e == 1)
    return (b % MOD);
  ll v = cpow(b, e / 2);
  v = (v * v) % MOD;
  if (e % 2 == 1)
    v = (v * b) % MOD;
  return v;
}

ll inv(ll x) { return cpow(x, MOD - 2); }

ll mscore[MAXN];
ll iscore[MAXN];

int L, N;
int ncross[MAXN];
ll np[MAXN];

pair<ll, ll> ps[MAXN];

int main() {
  ios_base::sync_with_stdio(0);

  mscore[0] = 1;
  iscore[0] = 1;
  mscore[1] = 1;
  for (int i = 2; i < (1 << 18); i++) {
    mscore[i] = (i * mscore[i / 2]) % MOD;
  }
  for (int i = 1; i < (1 << 18); i++)
    iscore[i] = inv((mscore[i] * mscore[i / 2]) % MOD);

  cin >> L;
  N = (1 << (L - 1));
  for (int i = 0; i < N; i++) {
    cin >> ncross[i];
    ncross[i]--;
    np[i] = (mscore[i + N] * mscore[ncross[i] + N]) % MOD;
  }

  ll ans = 0;
  for (int i = 0; i < L - 1; i++)
    for (int j = 0; j < L - 1; j++) {
      if (i + j <= 17) {
        for (int k = 0; k < (1 << (i + j + 1)); k++)
          ps[k] = make_pair(0, 0);
        for (int k = 0; k < N; k++) {
          ll v = (k >> (L - 1 - i)) * (1LL << j) + (ncross[k] >> (L - 1 - j));
          int b1 = (k >> (L - 2 - i) & 1);
          int b2 = (ncross[k] >> (L - 2 - j)) & 1;
          v = 2 * v + (b1 ^ b2);
          if (b2)
            ps[v].second += np[k];
          else
            ps[v].first += np[k];
        }

        for (int k = 0; k < (1 << (i + j + 1)); k++) {
          ll l = ps[k].first % MOD, l2 = ps[k].second % MOD;
          // cout << i << " " << j << " " << l << " " << l2 << "\\n";

          ll v = (l * l2) % MOD;
          if (!v)
            continue;
          ll mask = k;
          int a1 = (1 << i) + (mask / (1 << (j + 1)));
          int a2 = (1 << j) + (mask / 2) % (1 << j);
          // cout << mask << " " << a1 << " " << a2 << "\\n";
          v = v * (iscore[a1]) % MOD;
          v = v * (iscore[a2]) % MOD;
          ans += v;
        }
      } else if (i + j <= 29) {
        unordered_map<int, pair<ll, ll>> mm;
        for (int k = 0; k < N; k++) {
          ll v = (k >> (L - 1 - i)) * (1LL << j) + (ncross[k] >> (L - 1 - j));
          int b1 = (k >> (L - 2 - i) & 1);
          int b2 = (ncross[k] >> (L - 2 - j)) & 1;
          v = 2 * v + (b1 ^ b2);
          if (b2)
            mm[v].second += np[k];
          else
            mm[v].first += np[k];
        }

        for (auto it = mm.begin(); it != mm.end(); it++) {
          ll l = it->second.first % MOD, l2 = it->second.second % MOD;
          // cout << i << " " << j << " " << l << " " << l2 << "\\n";

          ll v = (l * l2) % MOD;
          if (!v)
            continue;
          ll mask = it->first;
          int a1 = (1 << i) + (mask / (1 << (j + 1)));
          int a2 = (1 << j) + (mask / 2) % (1 << j);
          // cout << mask << " " << a1 << " " << a2 << "\\n";
          v = v * (iscore[a1]) % MOD;
          v = v * (iscore[a2]) % MOD;
          ans += v;
        }
      } else {
        unordered_map<ll, pair<ll, ll>> mm;
        for (int k = 0; k < N; k++) {
          ll v = (k >> (L - 1 - i)) * (1LL << j) + (ncross[k] >> (L - 1 - j));
          int b1 = (k >> (L - 2 - i) & 1);
          int b2 = (ncross[k] >> (L - 2 - j)) & 1;
          v = 2 * v + (b1 ^ b2);
          if (b2)
            mm[v].second += np[k];
          else
            mm[v].first += np[k];
        }

        for (auto it = mm.begin(); it != mm.end(); it++) {
          ll l = it->second.first % MOD, l2 = it->second.second % MOD;
          // cout << i << " " << j << " " << l << " " << l2 << "\\n";

          ll v = (l * l2) % MOD;
          if (!v)
            continue;
          ll mask = it->first;
          int a1 = (1 << i) + (mask / (1 << (j + 1)));
          int a2 = (1 << j) + (mask / 2) % (1 << j);
          // cout << mask << " " << a1 << " " << a2 << "\\n";
          v = v * (iscore[a1]) % MOD;
          v = v * (iscore[a2]) % MOD;
          ans += v;
        }
      }
    }
  ans %= MOD;
  cout << ans << "\\n";
}