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

#include <cstdio>
#include <iostream>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
using llong = long long;
#define BUGO(x) cerr << #x << " = " << (x) << '\\n';
#define BUGOARR(a)                                                             \\
  {                                                                            \\
    cerr << #a << ": ";                                                        \\
    for (auto i : a)                                                           \\
      cerr << i << ' ';                                                        \\
    cerr << '\\n';                                                              \\
  }
#ifndef MANSON
#define BUGO(x)
#define BUGOARR(x)
#endif
ostream &operator<<(ostream &out, const pair<auto, auto> &p) {
  return out << "{" << p.first << ", " << p.second << "}";
}
const int mod = 1000'000'007LL;

int n, k, h, ans;
int a[1 << 18];

inline int mul(int a, int b) { return a * (llong)b % mod; }
void DFS(int v, int prod, vector<pair<int, int>> &leaves) {
  prod = mul(prod, v);
  if (v >= k) {
    leaves.push_back({v, prod});
    return;
  }
  DFS(v * 2, prod, leaves);
  DFS(v * 2 + 1, prod, leaves);
}
int main() {
  scanf("%d", &h);
  k = (1 << (h - 1));
  n = 2 * k - 1;
  vector<int> edges(k);
  for (int &i : edges)
    scanf("%d", &i), --i;
  int ans = 0;
  vector<int> clean;
  vector<pair<int, int>> l, r;
  for (int root = 1; root < k; ++root) {
    l.clear();
    r.clear();
    DFS(root * 2, root, l);
    DFS(root * 2 + 1, 1, r);
    clean.clear();
    for (auto p : l)
      for (int v = edges[p.first - k] + k, prod = p.second; v > 1; v /= 2) {
        prod = mul(prod, v);
        clean.push_back(v);
        a[v] += prod;
        if (a[v] >= mod)
          a[v] -= mod;
      }
    for (auto p : r)
      for (int v = edges[p.first - k] + k, prod = p.second; v > 1; v /= 2) {
        prod = mul(prod, v);
        BUGO(v)
        BUGO(prod)
        BUGO(a[v ^ 1])
        ans += mul(mul(a[v ^ 1], prod), v / 2);
        if (ans >= mod)
          ans -= mod;
      }
    for (int v : clean)
      a[v] = 0;
  }
  printf("%d", ans);
}


Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
using llong = long long;
#define BUGO(x) cerr << #x << " = " << (x) << '\\n';
#define BUGOARR(a)                                                             \\
  {                                                                            \\
    cerr << #a << ": ";                                                        \\
    for (auto i : a)                                                           \\
      cerr << i << ' ';                                                        \\
    cerr << '\\n';                                                              \\
  }
#ifndef MANSON
#define BUGO(x)
#define BUGOARR(x)
#endif
const int mod = 1000'000'007LL;

unordered_map<int, int> dp[1 << 18];

inline int mul(int a, int b) { return a * (llong)b % mod; }
int main() {
  int h;
  scanf("%d", &h);
  int k = (1 << (h - 1));
  vector<int> edges(k);
  for (int &i : edges)
    scanf("%d", &i);
  llong ans = 0;
  for (int v = k; v < 2 * k; ++v) {
    int u = k - 1 + edges[v - k];
    llong prod1 = 1;
    for (int a = u; a; a >>= 1) {
      prod1 = mul(prod1, a);
      llong prod2 = 1;
      for (int b = v; b; b >>= 1) {
        prod2 = mul(prod2, b);
        dp[a][b] = dp[a][b] + mul(prod1, prod2);
        if (dp[a][b] >= mod)
          dp[a][b] -= mod;
        if (a > 1 && b > 1) {
          ans += mul(mul(mul(prod1, prod2), dp[a ^ 1][b ^ 1]),
                     mul(a / 2LL, b / 2LL));
          if (ans >= mod)
            ans -= mod;
        }
      }
    }
  }
  printf("%lld", ans);
}