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

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rng(i, l, r) for (int i = int(l); i < int(r); i++)
#define rep(i, r) rng(i, 0, r)
#define rrng(i, l, r) for (int i = int(r) - 1; i >= int(l); i--)
#define rrep(i, r) rrng(i, 0, r)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define F first
#define S second
#define bg begin()
#define ed end()
#define all(x) x.bg, x.ed
#define si(x) int(x.size())
#define inf INT_MAX / 2 - 100
#define infl LLONG_MAX / 3
#ifdef LOCAL
#define dmp(x) cerr << __LINE__ << ' ' << #x << ' ' << x << endl
#else
#define dmp(x) void(0)
#endif

template <class t, class u> bool chmax(t &a, u b) {
  if (a < b)
    a = b;
  return a < b;
}
template <class t, class u> bool chmin(t &a, u b) {
  if (b < a)
    a = b;
  return b < a;
}

template <class t> using vc = vector<t>;
template <class t> using vvc = vector<vector<t>>;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vc<int>;
using vl = vc<ll>;

ll readl(void) {
  ll x;
  cin >> x;
  return x;
}
int readi(void) {
  int x;
  cin >> x;
  return x;
}

string readstr() {
  string s;
  cin >> s;
  return s;
}
vi readvi(int n, int off = 0) {
  vi v(n);
  rep(i, n) v[i] = readi(), v[i] += off;
  return v;
}

vl readvl(int n, int off = 0) {
  vl v(n);
  rep(i, n) v[i] = readl(), v[i] += off;
  return v;
}

template <class t> void print(t x, int suc = 1) {
  cout << x;
  if (suc == 1)
    cout << "\\n";
  if (suc == 2)
    cout << " ";
}

template <class t> void print(const vc<t> &v, int suc = 1) {
  rep(i, si(v)) print(v[i], i == int(si(v)) - 1 ? 1 : suc);
}

template <class t> bool inc(t a, t b, t c) { return !(c < b || b < a); }

template <class t> void compress(vc<t> &v) {
  sort(all(v));
  v.erase(unique(all(v)), v.ed);
}

template <class t> int lwb(const vc<t> &v, const t &a) {
  return lower_bound(all(v), a) - v.bg;
}

template <class t> struct Compress {
  vc<t> v;
  Compress() = default;
  Compress(const vc<t> &x) { add(x); }
  Compress(const initializer_list<vc<t>> &x) {
    for (auto &p : x)
      add(p);
  }
  void add(const t &x) { v.eb(x); }
  void add(const vc<t> &x) { copy(all(x), back_inserter(v)); }
  void build() { compress(v); }
  int get(const t &x) const { return lwb(v, x); }
  vc<t> get(const vc<t> &x) const {
    vc<t> res(x);
    for (auto &p : res)
      p = get(p);
    return res;
  }
  const t &operator[](int x) const { return v[x]; }
  int size() { return v.size(); }
};
void Yes(bool ex = true) {
  cout << "Yes\\n";
  if (ex)
    exit(0);
}
void YES(bool ex = true) {
  cout << "YES\\n";
  if (ex)
    exit(0);
}
void No(bool ex = true) {
  cout << "No\\n";
  if (ex)
    exit(0);
}
void NO(bool ex = true) {
  cout << "NO\\n";
  if (ex)
    exit(0);
}
void orYes(bool x, bool ex = true) {
  if (x)
    Yes(ex);
  else
    No(ex);
}
void orYES(bool x, bool ex = true) {
  if (x)
    YES(ex);
  else
    NO(ex);
}
void Possible(bool ex = true) {
  cout << "Possible\\n";
  if (ex)
    exit(0);
}
void POSSIBLE(bool ex = true) {
  cout << "POSSIBLE\\n";
  if (ex)
    exit(0);
}
void Impossible(bool ex = true) {
  cout << "Impossible\\n";
  if (ex)
    exit(0);
}
void IMPOSSIBLE(bool ex = true) {
  cout << "IMPOSSIBLE\\n";
  if (ex)
    exit(0);
}
void orPossible(bool x, bool ex = true) {
  if (x)
    Possible(ex);
  else
    Impossible(ex);
}
void orPOSSIBLE(bool x, bool ex = true) {
  if (x)
    POSSIBLE(ex);
  else
    IMPOSSIBLE(ex);
}

using uint = unsigned;
using ull = unsigned long long;

template <uint const &MOD> struct Modular {
  static constexpr uint const &mod = MOD;
  uint v;
  Modular(long long x = 0) { c(x % mod + mod); }
  Modular &c(uint x) {
    v = x < mod ? x : x - mod;
    return *this;
  }
  Modular pow(int k) const {
    Modular res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Modular inv() const { return pow(mod - 2); }
  Modular operator-() const { return Modular(mod - v); }

  Modular &operator+=(const Modular &x) { return c(v + x.v); }
  Modular &operator-=(const Modular &x) { return c(v + mod - x.v); }
  Modular &operator*=(const Modular &x) {
    v = ull(v) * x.v % mod;
    return *this;
  }
  Modular &operator/=(const Modular &x) { return *this *= x.inv(); }

  Modular operator+(const Modular &x) const { return Modular(*this) += x; }
  Modular operator-(const Modular &x) const { return Modular(*this) -= x; }
  Modular operator*(const Modular &x) const { return Modular(*this) *= x; }
  Modular operator/(const Modular &x) const { return Modular(*this) /= x; }

  friend Modular operator+(long long x, const Modular &y) {
    return Modular(x) + y;
  }
  friend Modular operator-(long long x, const Modular &y) {
    return Modular(x) - y;
  }
  friend Modular operator*(long long x, const Modular &y) {
    return Modular(x) * y;
  }
  friend Modular operator/(long long x, const Modular &y) {
    return Modular(x) / y;
  }

  friend ostream &operator<<(ostream &os, const Modular &x) {
    return os << x.v;
  }
  friend istream &operator>>(istream &is, Modular &x) {
    long long p;
    is >> p;
    x = Modular(p);
    return is;
  }
  bool operator==(const Modular &x) const { return v == x.v; }
  bool operator!=(const Modular &x) const { return v != x.v; }
  bool operator<(const Modular &x) const { return v < x.v; }
  explicit operator bool() const { return v; }
};

// uint MODULAR=998244353;
uint MODULAR = 1000000007;
using Mint = Modular<MODULAR>;

vector<Mint> fact, finv, invs;
void Initfact(int n = (1 << 21) + 10) {
  fact.resize(n + 1), finv.resize(n + 1), invs.resize(n + 1);
  fact[0] = 1;
  for (int i = 1; i <= n; i++) {
    fact[i] = fact[i - 1] * i;
  }
  finv[n] = fact[n].inv();
  for (int i = n - 1; i >= 0; i--) {
    finv[i] = finv[i + 1] * (i + 1);
  }
  invs[0] = 1;
  for (int i = 0; i <= n; i++) {
    invs[i] = finv[i] * fact[i - 1];
  }
}

Mint comb(int n, int k) { return fact[n] * finv[n - k] * finv[k]; }

int h;
Mint r[(1 << 18) + 1], invr[(1 << 18) + 1], ans;
Mint sum[(1 << 19) + 1][2];
vector<pair<int, Mint>> pp[(1 << 18) + 1][2];
bool vis[(1 << 18) + 1];
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> h;
  for (int i = 1; i < 1 << h; i++) {
    r[i] = i;
    if (i / 2 > 0)
      r[i] *= r[i / 2];
    invr[i] = r[i].inv() * r[i].inv() * Mint(i);
  }
  for (int i = 0; i < 1 << (h - 1); i++) {
    int p;
    cin >> p;
    p--;
    p += (1 << (h - 1));
    int v = i + (1 << (h - 1));
    Mint q = r[p] * r[v];
    while (v > 1) {
      pp[v / 2][v % 2].pb(mp(p, q));
      v /= 2;
    }
  }
  for (int i = 1; i < 1 << (h - 1); i++) {
    queue<int> lis;
    for (int j = 0; j < 2; j++) {
      for (auto &k : pp[i][j]) {
        sum[k.F][j] += k.S;
        if (!vis[k.F]) {
          lis.push(k.F);
          vis[k.F] = true;
        }
      }
    }
    while (!lis.empty()) {
      int v = lis.front();
      lis.pop();
      vis[v] = false;
      for (int j = 0; j < 2; j++) {
        ans += sum[v * 2][j] * sum[v * 2 + 1][(j + 1) % 2] * invr[v] * invr[i];
        sum[v][j] += sum[v * 2][j] + sum[v * 2 + 1][j];
      }
      for (int j = 0; j < 2; j++) {
        sum[v * 2][j] = 0;
        sum[v * 2 + 1][j] = 0;
      }
      if (v / 2 > 0 && !vis[v / 2]) {
        lis.push(v / 2);
        vis[v / 2] = true;
      }
    }
  }
  print(ans);
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rng(i, l, r) for (int i = int(l); i < int(r); i++)
#define rep(i, r) rng(i, 0, r)
#define rrng(i, l, r) for (int i = int(r) - 1; i >= int(l); i--)
#define rrep(i, r) rrng(i, 0, r)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define F first
#define S second
#define bg begin()
#define ed end()
#define all(x) x.bg, x.ed
#define si(x) int(x.size())
#define inf INT_MAX / 2 - 100
#define infl LLONG_MAX / 3
#ifdef LOCAL
#define dmp(x) cerr << __LINE__ << ' ' << #x << ' ' << x << endl
#else
#define dmp(x) void(0)
#endif

template <class t, class u> bool chmax(t &a, u b) {
  if (a < b)
    a = b;
  return a < b;
}
template <class t, class u> bool chmin(t &a, u b) {
  if (b < a)
    a = b;
  return b < a;
}

template <class t> using vc = vector<t>;
template <class t> using vvc = vector<vector<t>>;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vc<int>;
using vl = vc<ll>;

ll readl(void) {
  ll x;
  cin >> x;
  return x;
}
int readi(void) {
  int x;
  cin >> x;
  return x;
}

string readstr() {
  string s;
  cin >> s;
  return s;
}
vi readvi(int n, int off = 0) {
  vi v(n);
  rep(i, n) v[i] = readi(), v[i] += off;
  return v;
}

vl readvl(int n, int off = 0) {
  vl v(n);
  rep(i, n) v[i] = readl(), v[i] += off;
  return v;
}

template <class t> void print(t x, int suc = 1) {
  cout << x;
  if (suc == 1)
    cout << "\\n";
  if (suc == 2)
    cout << " ";
}

template <class t> void print(const vc<t> &v, int suc = 1) {
  rep(i, si(v)) print(v[i], i == int(si(v)) - 1 ? 1 : suc);
}

template <class t> bool inc(t a, t b, t c) { return !(c < b || b < a); }

template <class t> void compress(vc<t> &v) {
  sort(all(v));
  v.erase(unique(all(v)), v.ed);
}

template <class t> int lwb(const vc<t> &v, const t &a) {
  return lower_bound(all(v), a) - v.bg;
}

template <class t> struct Compress {
  vc<t> v;
  Compress() = default;
  Compress(const vc<t> &x) { add(x); }
  Compress(const initializer_list<vc<t>> &x) {
    for (auto &p : x)
      add(p);
  }
  void add(const t &x) { v.eb(x); }
  void add(const vc<t> &x) { copy(all(x), back_inserter(v)); }
  void build() { compress(v); }
  int get(const t &x) const { return lwb(v, x); }
  vc<t> get(const vc<t> &x) const {
    vc<t> res(x);
    for (auto &p : res)
      p = get(p);
    return res;
  }
  const t &operator[](int x) const { return v[x]; }
  int size() { return v.size(); }
};
void Yes(bool ex = true) {
  cout << "Yes\\n";
  if (ex)
    exit(0);
}
void YES(bool ex = true) {
  cout << "YES\\n";
  if (ex)
    exit(0);
}
void No(bool ex = true) {
  cout << "No\\n";
  if (ex)
    exit(0);
}
void NO(bool ex = true) {
  cout << "NO\\n";
  if (ex)
    exit(0);
}
void orYes(bool x, bool ex = true) {
  if (x)
    Yes(ex);
  else
    No(ex);
}
void orYES(bool x, bool ex = true) {
  if (x)
    YES(ex);
  else
    NO(ex);
}
void Possible(bool ex = true) {
  cout << "Possible\\n";
  if (ex)
    exit(0);
}
void POSSIBLE(bool ex = true) {
  cout << "POSSIBLE\\n";
  if (ex)
    exit(0);
}
void Impossible(bool ex = true) {
  cout << "Impossible\\n";
  if (ex)
    exit(0);
}
void IMPOSSIBLE(bool ex = true) {
  cout << "IMPOSSIBLE\\n";
  if (ex)
    exit(0);
}
void orPossible(bool x, bool ex = true) {
  if (x)
    Possible(ex);
  else
    Impossible(ex);
}
void orPOSSIBLE(bool x, bool ex = true) {
  if (x)
    POSSIBLE(ex);
  else
    IMPOSSIBLE(ex);
}

using uint = unsigned;
using ull = unsigned long long;

template <uint const &MOD> struct Modular {
  static constexpr uint const &mod = MOD;
  uint v;
  Modular(long long x = 0) { c(x % mod + mod); }
  Modular &c(uint x) {
    v = x < mod ? x : x - mod;
    return *this;
  }
  Modular pow(int k) const {
    Modular res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Modular inv() const { return pow(mod - 2); }
  Modular operator-() const { return Modular(mod - v); }

  Modular &operator+=(const Modular &x) { return c(v + x.v); }
  Modular &operator-=(const Modular &x) { return c(v + mod - x.v); }
  Modular &operator*=(const Modular &x) {
    v = ull(v) * x.v % mod;
    return *this;
  }
  Modular &operator/=(const Modular &x) { return *this *= x.inv(); }

  Modular operator+(const Modular &x) const { return Modular(*this) += x; }
  Modular operator-(const Modular &x) const { return Modular(*this) -= x; }
  Modular operator*(const Modular &x) const { return Modular(*this) *= x; }
  Modular operator/(const Modular &x) const { return Modular(*this) /= x; }

  friend Modular operator+(long long x, const Modular &y) {
    return Modular(x) + y;
  }
  friend Modular operator-(long long x, const Modular &y) {
    return Modular(x) - y;
  }
  friend Modular operator*(long long x, const Modular &y) {
    return Modular(x) * y;
  }
  friend Modular operator/(long long x, const Modular &y) {
    return Modular(x) / y;
  }

  friend ostream &operator<<(ostream &os, const Modular &x) {
    return os << x.v;
  }
  friend istream &operator>>(istream &is, Modular &x) {
    long long p;
    is >> p;
    x = Modular(p);
    return is;
  }
  bool operator==(const Modular &x) const { return v == x.v; }
  bool operator!=(const Modular &x) const { return v != x.v; }
  bool operator<(const Modular &x) const { return v < x.v; }
  explicit operator bool() const { return v; }
};

// uint MODULAR=998244353;
uint MODULAR = 1000000007;
using Mint = Modular<MODULAR>;

vector<Mint> fact, finv, invs;
void Initfact(int n = (1 << 21) + 10) {
  fact.resize(n + 1), finv.resize(n + 1), invs.resize(n + 1);
  fact[0] = 1;
  for (int i = 1; i <= n; i++) {
    fact[i] = fact[i - 1] * i;
  }
  finv[n] = fact[n].inv();
  for (int i = n - 1; i >= 0; i--) {
    finv[i] = finv[i + 1] * (i + 1);
  }
  invs[0] = 1;
  for (int i = 0; i <= n; i++) {
    invs[i] = finv[i] * fact[i - 1];
  }
}

Mint comb(int n, int k) { return fact[n] * finv[n - k] * finv[k]; }

int h;
Mint r[(1 << 18) + 1], invr[(1 << 18) + 1], ans;
map<int, Mint> sum[(1 << 18) + 1][2];
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> h;
  for (int i = 1; i < 1 << h; i++) {
    r[i] = i;
    if (i / 2 > 0)
      r[i] *= r[i / 2];
    invr[i] = r[i].inv() * r[i].inv() * Mint(i);
  }
  for (int i = 0; i < 1 << (h - 1); i++) {
    int p;
    cin >> p;
    p--;
    p += (1 << (h - 1));
    int v = i + (1 << (h - 1));
    Mint q = r[p] * r[v];
    while (v > 1) {
      sum[p][v % 2][v / 2] += q;
      v /= 2;
    }
  }
  for (int i = (1 << (h - 1)) - 1; i > 0; i--) {
    map<int, Mint> *x = sum[i * 2];
    map<int, Mint> *y = sum[i * 2 + 1];
    map<int, Mint> *z = sum[i];
    Mint s = 0;
    for (auto &k : x[0]) {
      s += invr[k.F] * k.S * y[1][k.F];
      z[0][k.F] += k.S;
    }
    for (auto &k : y[0]) {
      z[0][k.F] += k.S;
    }
    for (auto &k : x[1]) {
      s += invr[k.F] * k.S * y[0][k.F];
      z[1][k.F] += k.S;
    }
    for (auto &k : y[1]) {
      z[1][k.F] += k.S;
    }
    ans += s * invr[i];
  }
  print(ans);
}