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

#include <algorithm>
#include <assert.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unordered_map>

using namespace std;

typedef long long ll;

const int MAXN = 262150;
const ll MOD = 1000000007;

int n;
int p[MAXN];

ll ans;
ll val1[MAXN];
ll val2[MAXN];
ll sum[MAXN];

pair<int, ll> mdf[MAXN][18];
pair<int, ll> qry[MAXN][18];

int main() {
  scanf("%d", &n);
  for (int i = 0; i < (1 << (n - 1)); i++) {
    scanf("%d", &p[i]);
    p[i]--;
  }
  for (int L = 0; L < n - 1; L++) {
    for (int i = 0; i < (1 << (n - 1)); i++) {
      int u = i + (1 << (n - 1)), v = p[i] + (1 << (n - 1));
      ll vu = 1, vv = 1;
      for (int j = u; j >= 1; j >>= 1) {
        (vu *= j) %= MOD;
        val1[j] = vu;
      }
      for (int j = v; j >= 1; j >>= 1) {
        (vv *= j) %= MOD;
        val2[j] = vv;
      }
      for (int j = u, l = 0; j >= 1; j >>= 1, l++)
        if (l == L)
          for (int k = v, r = 0; k >= 1; k >>= 1, r++)
            mdf[u][r] = make_pair(k, val1[j] * val2[k] % MOD);
    }
    for (int i = 0; i < (1 << (n - 1)); i++) {
      int u = i + (1 << (n - 1)), v = p[i] + (1 << (n - 1));
      ll vu = 1, vv = 1;
      for (int j = u; j >= 1; j >>= 1) {
        (vu *= j) %= MOD;
        val1[j] = vu;
      }
      for (int j = v; j >= 1; j >>= 1) {
        (vv *= j) %= MOD;
        val2[j] = vv;
      }
      for (int j = u, l = 0; j >= 2; j >>= 1, l++)
        if (l == L)
          for (int k = v, r = 0; k >= 2; k >>= 1, r++)
            qry[u ^ (1 << L)][r] =
                make_pair(k ^ 1, val1[j >> 1] * val2[k >> 1] % MOD);
    }
    for (int i = (1 << (n - 1 - L)); i < (1 << (n - L)); i++) {
      for (int j = i << L; j < (i << L) + (1 << L); j++)
        for (int k = 0; k < n; k++)
          (sum[mdf[j][k].first] += mdf[j][k].second) %= MOD;
      for (int j = i << L; j < (i << L) + (1 << L); j++)
        for (int k = 0; k < n; k++)
          (ans += sum[qry[j][k].first] * qry[j][k].second) %= MOD;
      for (int j = i << L; j < (i << L) + (1 << L); j++)
        for (int k = 0; k < n; k++)
          sum[mdf[j][k].first] = 0;
    }
  }
  printf("%lld\\n", ans * ((MOD + 1) / 2) % MOD);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unordered_map>

using namespace std;

typedef long long ll;

const int MAXN = 262150;
const ll MOD = 1000000007;

int n;
int p[MAXN];

ll ans;
ll val1[MAXN];
ll val2[MAXN];
ll sum[MAXN];

vector<pair<int, ll>> mdf[MAXN];
vector<pair<int, ll>> qry[MAXN];

int main() {
  scanf("%d", &n);
  for (int i = 0; i < (1 << (n - 1)); i++) {
    scanf("%d", &p[i]);
    p[i]--;
  }
  for (int L = 0; L < n; L++) {
    for (int i = 0; i < (1 << (n - 1)); i++) {
      int u = i + (1 << (n - 1)), v = p[i] + (1 << (n - 1));
      ll vu = 1, vv = 1;
      for (int j = u; j >= 1; j >>= 1) {
        (vu *= j) %= MOD;
        val1[j] = vu;
      }
      for (int j = v; j >= 1; j >>= 1) {
        (vv *= j) %= MOD;
        val2[j] = vv;
      }
      for (int j = u, l = 0; j >= 1; j >>= 1, l++)
        if (l == L)
          for (int k = v; k >= 1; k >>= 1)
            mdf[j].push_back(make_pair(k, val1[j] * val2[k] % MOD));
    }
    for (int i = 0; i < (1 << (n - 1)); i++) {
      int u = i + (1 << (n - 1)), v = p[i] + (1 << (n - 1));
      ll vu = 1, vv = 1;
      for (int j = u; j >= 1; j >>= 1) {
        (vu *= j) %= MOD;
        val1[j] = vu;
      }
      for (int j = v; j >= 1; j >>= 1) {
        (vv *= j) %= MOD;
        val2[j] = vv;
      }
      for (int j = u, l = 0; j >= 1; j >>= 1, l++)
        if (l == L)
          for (int k = v; k >= 2; k >>= 1)
            qry[j ^ 1].push_back(
                make_pair(k ^ 1, val1[j >> 1] * val2[k >> 1] % MOD));
    }
    for (int i = 1; i < (1 << n); i++) {
      for (int j = 0; j < mdf[i].size(); j++)
        (sum[mdf[i][j].first] += mdf[i][j].second) %= MOD;
      for (int j = 0; j < qry[i].size(); j++)
        (ans += sum[qry[i][j].first] * qry[i][j].second) %= MOD;
      for (int j = 0; j < mdf[i].size(); j++)
        sum[mdf[i][j].first] = 0;
      mdf[i].clear();
      qry[i].clear();
    }
  }
  printf("%lld\\n", ans * ((MOD + 1) / 2) % MOD);
  return 0;
}