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

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author majk
 */

#ifndef MAJK_LIB
#define MAJK_LIB

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#define x first
#define y second
typedef std::pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef pair<ui, ui> puu;

template <typename T, typename U>
std::istream &operator>>(std::istream &i, pair<T, U> &p) {
  i >> p.x >> p.y;
  return i;
}
template <typename T> std::istream &operator>>(std::istream &i, vector<T> &t) {
  for (auto &v : t) {
    i >> v;
  }
  return i;
}
template <typename T, typename U>
std::ostream &operator<<(std::ostream &o, const pair<T, U> &p) {
  o << p.x << ' ' << p.y;
  return o;
}
template <typename T>
std::ostream &operator<<(std::ostream &o, const vector<T> &t) {
  if (t.empty())
    o << '\\n';
  for (size_t i = 0; i < t.size(); ++i) {
    o << t[i] << " \\n"[i == t.size() - 1];
  }
  return o;
}
template <typename T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using maxheap = priority_queue<T, vector<T>, less<T>>;
ui logceil(ll x) { return x ? 8 * sizeof(ll) - __builtin_clzll(x) : 0; }

namespace std {
template <typename T, typename U> struct hash<pair<T, U>> {
  hash<T> t;
  hash<U> u;
  size_t operator()(const pair<T, U> &p) const {
    return t(p.x) ^ (u(p.y) << 7);
  }
};
} // namespace std
template <typename T, typename F> T bsh(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      l = m + 1;
      r = m;
    } else {
      h = m - 1;
    }
  }
  return r;
}
template <typename F>
double bshd(double l, double h, const F &f, double p = 1e-9) {
  ui r = 3 + (ui)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      l = m;
    } else {
      h = m;
    }
  }
  return (l + h) / 2;
}
template <typename T, typename F> T bsl(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      h = m - 1;
      r = m;
    } else {
      l = m + 1;
    }
  }
  return r;
}
template <typename F> double bsld(double l, double h, const F &f) {
  ui r = 200;
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      h = m;
    } else {
      l = m;
    }
  }
  return (l + h) / 2;
}
template <typename T> T gcd(T a, T b) {
  if (a < b)
    swap(a, b);
  return b ? gcd(b, a % b) : a;
}

template <typename T> class vector2 : public vector<vector<T>> {
public:
  vector2() {}
  vector2(size_t a, size_t b, T t = T())
      : vector<vector<T>>(a, vector<T>(b, t)) {}
};
template <typename T> class vector3 : public vector<vector2<T>> {
public:
  vector3() {}
  vector3(size_t a, size_t b, size_t c, T t = T())
      : vector<vector2<T>>(a, vector2<T>(b, c, t)) {}
};
template <typename T> class vector4 : public vector<vector3<T>> {
public:
  vector4() {}
  vector4(size_t a, size_t b, size_t c, size_t d, T t = T())
      : vector<vector3<T>>(a, vector3<T>(b, c, d, t)) {}
};
template <typename T> class vector5 : public vector<vector4<T>> {
public:
  vector5() {}
  vector5(size_t a, size_t b, size_t c, size_t d, size_t e, T t = T())
      : vector<vector4<T>>(a, vector4<T>(b, c, d, e, t)) {}
};

#endif
#ifndef MOD_H
#define MOD_H

template <unsigned int N> class Field {
  typedef unsigned int ui;
  typedef unsigned long long ull;
  inline ui pow(ui a, ui p) {
    ui r = 1, e = a;
    while (p) {
      if (p & 1) {
        r = ((ull)r * e) % N;
      }
      e = ((ull)e * e) % N;
      p >>= 1;
    }
    return r;
  }
  /*extended GCD(slow):ll t=0,nt=1,r=N,nr=a;while(nr){ll
   * q=r/nr;t-=q*nt;swap(t,nt);r-=q*nr;swap(r,nr);}assert(r<=1);return(t<0)?t+N:t;*/
  inline ui inv(ui a) { return pow(a, N - 2); }

public:
  inline Field(int x = 0) : v(x < 0 ? N + x : x) {}
  inline Field<N> pow(int p) { return (*this) ^ p; }
  inline Field<N> operator^(int p) { return {(int)pow(v, (ui)p)}; }
  inline Field<N> &operator+=(const Field<N> &o) {
    if (v + o.v >= N)
      v += o.v - N;
    else
      v += o.v;
    return *this;
  }
  inline Field<N> &operator-=(const Field<N> &o) {
    if (v < o.v)
      v -= o.v - N;
    else
      v -= o.v;
    return *this;
  }
  inline Field<N> &operator*=(const Field<N> &o) {
    v = (ull)v * o.v % N;
    return *this;
  }
  inline Field<N> &operator/=(const Field<N> &o) { return *this *= inv(o.v); }
  inline Field<N> operator+(const Field<N> &o) const {
    Field<N> r{*this};
    return r += o;
  }
  inline Field<N> operator-(const Field<N> &o) const {
    Field<N> r{*this};
    return r -= o;
  }
  inline Field<N> operator*(const Field<N> &o) const {
    Field<N> r{*this};
    return r *= o;
  }
  inline Field<N> operator/(const Field<N> &o) const {
    Field<N> r{*this};
    return r /= o;
  }
  inline Field<N> operator-() {
    if (v)
      return {(int)(N - v)};
    else
      return {0};
  };
  inline Field<N> &operator++() {
    ++v;
    if (v == N)
      v = 0;
    return *this;
  }
  inline Field<N> operator++(int) {
    Field<N> r{*this};
    ++*this;
    return r;
  }
  inline Field<N> &operator--() {
    --v;
    if (v == -1)
      v = N - 1;
    return *this;
  }
  inline Field<N> operator--(int) {
    Field<N> r{*this};
    --*this;
    return r;
  }
  inline bool operator==(const Field<N> &o) const { return o.v == v; }
  inline bool operator!=(const Field<N> &o) const { return o.v != v; }
  inline explicit operator ui() const { return v; }
  inline static vector<Field<N>> fact(int t) {
    vector<Field<N>> F(t + 1, 1);
    for (int i = 2; i <= t; ++i) {
      F[i] = F[i - 1] * i;
    }
    return F;
  }
  inline static vector<Field<N>> invfact(int t) {
    vector<Field<N>> F(t + 1, 1);
    Field<N> X{1};
    for (int i = 2; i <= t; ++i) {
      X = X * i;
    }
    F[t] = 1 / X;
    for (int i = t - 1; i >= 2; --i) {
      F[i] = F[i + 1] * (i + 1);
    }
    return F;
  }

private:
  ui v;
};
template <unsigned int N> istream &operator>>(std::istream &is, Field<N> &f) {
  unsigned int v;
  is >> v;
  f = v;
  return is;
}
template <unsigned int N>
ostream &operator<<(std::ostream &os, const Field<N> &f) {
  return os << (unsigned int)f;
}
template <unsigned int N> Field<N> operator+(int i, const Field<N> &f) {
  return Field<N>(i) + f;
}
template <unsigned int N> Field<N> operator-(int i, const Field<N> &f) {
  return Field<N>(i) - f;
}
template <unsigned int N> Field<N> operator*(int i, const Field<N> &f) {
  return Field<N>(i) * f;
}
template <unsigned int N> Field<N> operator/(int i, const Field<N> &f) {
  return Field<N>(i) / f;
}

typedef Field<1000000007> FieldMod;

struct Ring {
  template <typename T> static T div(T p, T q, T N) {
    T t = 0, nt = 1, r = N, nr = q;
    while (nr != 0) {
      T q = r / nr;
      t -= q * nt;
      r -= q * nr;
      swap(t, nt);
      swap(r, nr);
    }
    t = (t < 0) ? t + N : t;
    r = (r < 0) ? r + N : r;
    if (gcd(p, N) % r != 0) {
      return 0;
    }
    return (t * p / r) % N;
  }
};
#endif

template <typename T> struct Fenwick {
  explicit Fenwick(ui N = 0, T t = T())
      : N(1u << logceil(N)), F(this->N, t), t(t) {}
  explicit Fenwick(const vector<T> &A, T t = T())
      : N(1u << logceil(A.size())), F(A), t(t) {
    F.resize(N);
    fill(F.begin() + A.size(), F.end(), t);
    for (int i = 0; i < N; i++) {
      int j = i + lsb(i + 1);
      if (j < N)
        F[j] += F[i];
    }
  }
  void add(int i, T v) {
    while (i <= N) {
      F[i] += v;
      i += lsb(i + 1);
    }
  }
  T sum(int i) const {
    T sum(t);
    while (i) {
      sum += F[i - 1];
      i -= lsb(i);
    }
    return sum;
  }
  T range(int i, int j) const {
    j++;
    T s(t);
    while (j > i) {
      s += F[j - 1];
      j -= lsb(j);
    }
    while (i > j) {
      s -= F[i - 1];
      i -= lsb(i);
    }
    return s;
  }
  T get(int i) const { return range(i, i); }
  void set(int i, T v) { add(i, v - get(i)); }
  constexpr int lsb(int i) const { return i & -i; }
  ui N;
  vector<T> F;
  T t;
  int max_lower(T v) {
    // TODO: this returns suspicious results ...
    if (F[0] >= v)
      return -1;
    if (F[N - 1] < v)
      return N - 1;

    int x = 0;
    T a = t;
    for (int s = N >> 1; s > 0; s >>= 1)
      if (a + F[x + s - 1] < v) {
        a += F[x + s - 1];
        x += s;
      }
    return x;
  }
};

template <typename T> struct Fenwick2 {
  explicit Fenwick2(ui N = 0, T t = T())
      : N(1u << logceil(N)), F(this->N, this->N, t), t(t) {}
  //    explicit Fenwick2(const vector<vector<T>>&A, T
  //    t=T()):N(1u<<logceil(A.size())),F(A),t(t){
  //            F.resize(N);
  //            for (int i=0;i<A.size();++i) { F[i].resize(N);
  //            fill(F[i].begin()+A.size(),F[i].end(),t); } for (int
  //            i=A.size();i<N;++i) { F[i].resize(N);
  //            fill(F[i].begin(),F[i].end(),t); }
  //
  ////            for(int i=0;i<N;i++){int j=i+lsb(i+1);if(j<N)F[j]+=F[i];}
  //    }
  void add(int x, int y, T v) {
    while (x <= N) {
      int z = y;
      while (z <= N) {
        F[x][z] += v;
        z += lsb(z + 1);
      }
      x += lsb(x + 1);
    }
  }

  T sum(int x, int y) {
    T sum(t);
    while (x <= N) {
      int z = y;
      while (z <= N) {
        sum += F[x][z];
        z -= lsb(z + 1);
      }
      x -= lsb(x + 1);
    }
    return sum;
  }
  T range(int x1, int y1, int x2, int y2) {
    T ans = sum(x2, y2);
    if (x1)
      ans -= sum(x1 - 1, y2);
    if (y1)
      ans -= sum(x2, y1 - 1);
    if (x1 && y1)
      ans += sum(x1 - 1, y1 - 1);
    return ans;
  }
  constexpr int lsb(int i) const { return i & -i; }
  ui N;
  vector2<T> F;
  T t;
};

class DTwinBinaryTrees {
public:
  void solve(istream &cin, ostream &cout) {
    int H;
    cin >> H;
    int L = 1 << H >> 1;
    vector<int> P(L);
    cin >> P;
    for (int &p : P)
      --p;

    vector2<FieldMod> Z(H, L, 1);
    for (int i = 0; i < L; ++i) {
      int j = L + i;
      int h = H - 1;
      while (j != 1) {
        Z[h--][i] *= j;
        j /= 2;
      }
      for (int h = 1; h < H; ++h)
        Z[h][i] *= Z[h - 1][i];
    }

    vector<FieldMod> X(L, 1);
    for (int i = 0; i < L; ++i) {
      X[i] = Z[H - 1][i] * Z[H - 1][P[i]];
    }
    for (int i = 0; i < L; ++i) {
      for (int d = H - 1; d >= 1; --d) {
        Z[d][i] = FieldMod{1} / (Z[d][i] * Z[d - 1][i]);
      }
    }

    FieldMod ans = 0;
    Fenwick<FieldMod> F(L, 0);
    for (int h = 0; h < H - 1; ++h) {
      for (int a = 0; a < (1 << h); ++a) {
        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          F.add(P[s], X[s]);
        }

        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          for (int l = 0; l < H - 1; ++l) {
            int t = P[s] ^ (1 << l);
            int hi = t | ((1 << l) - 1);
            int lo = hi ^ ((1 << l) - 1);
            FieldMod ff = F.range(lo, hi);
            ff *= X[s];
            ff *= Z[H - 2 - l][P[s]];
            ans += ff * Z[h][s];
            if (h != 0)
              ans -= ff * Z[h - 1][s];
            //                        ff /= Z[H-2-l][P[s]] * Z[max(H-3-l,
            //                        0)][P[s]]; ans += ff / (Z[h][s] *
            //                        Z[max(h-1, 0)][s]); if (h != 0) ans -= ff
            //                        / (Z[h-1][s] * Z[max(h-2, 0)][s]);
          }
        }

        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          F.add(P[s], -X[s]);
        }
      }
    }

    cout << ans / 2 << '\\n';
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  DTwinBinaryTrees solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}


Error: TLE

Fixed submission:

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author majk
 */

#ifndef MAJK_LIB
#define MAJK_LIB

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#define x first
#define y second
typedef std::pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef pair<ui, ui> puu;

template <typename T, typename U>
std::istream &operator>>(std::istream &i, pair<T, U> &p) {
  i >> p.x >> p.y;
  return i;
}
template <typename T> std::istream &operator>>(std::istream &i, vector<T> &t) {
  for (auto &v : t) {
    i >> v;
  }
  return i;
}
template <typename T, typename U>
std::ostream &operator<<(std::ostream &o, const pair<T, U> &p) {
  o << p.x << ' ' << p.y;
  return o;
}
template <typename T>
std::ostream &operator<<(std::ostream &o, const vector<T> &t) {
  if (t.empty())
    o << '\\n';
  for (size_t i = 0; i < t.size(); ++i) {
    o << t[i] << " \\n"[i == t.size() - 1];
  }
  return o;
}
template <typename T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using maxheap = priority_queue<T, vector<T>, less<T>>;
ui logceil(ll x) { return x ? 8 * sizeof(ll) - __builtin_clzll(x) : 0; }

namespace std {
template <typename T, typename U> struct hash<pair<T, U>> {
  hash<T> t;
  hash<U> u;
  size_t operator()(const pair<T, U> &p) const {
    return t(p.x) ^ (u(p.y) << 7);
  }
};
} // namespace std
template <typename T, typename F> T bsh(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      l = m + 1;
      r = m;
    } else {
      h = m - 1;
    }
  }
  return r;
}
template <typename F>
double bshd(double l, double h, const F &f, double p = 1e-9) {
  ui r = 3 + (ui)log2((h - l) / p);
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      l = m;
    } else {
      h = m;
    }
  }
  return (l + h) / 2;
}
template <typename T, typename F> T bsl(T l, T h, const F &f) {
  T r = -1, m;
  while (l <= h) {
    m = (l + h) / 2;
    if (f(m)) {
      h = m - 1;
      r = m;
    } else {
      l = m + 1;
    }
  }
  return r;
}
template <typename F> double bsld(double l, double h, const F &f) {
  ui r = 200;
  while (r--) {
    double m = (l + h) / 2;
    if (f(m)) {
      h = m;
    } else {
      l = m;
    }
  }
  return (l + h) / 2;
}
template <typename T> T gcd(T a, T b) {
  if (a < b)
    swap(a, b);
  return b ? gcd(b, a % b) : a;
}

template <typename T> class vector2 : public vector<vector<T>> {
public:
  vector2() {}
  vector2(size_t a, size_t b, T t = T())
      : vector<vector<T>>(a, vector<T>(b, t)) {}
};
template <typename T> class vector3 : public vector<vector2<T>> {
public:
  vector3() {}
  vector3(size_t a, size_t b, size_t c, T t = T())
      : vector<vector2<T>>(a, vector2<T>(b, c, t)) {}
};
template <typename T> class vector4 : public vector<vector3<T>> {
public:
  vector4() {}
  vector4(size_t a, size_t b, size_t c, size_t d, T t = T())
      : vector<vector3<T>>(a, vector3<T>(b, c, d, t)) {}
};
template <typename T> class vector5 : public vector<vector4<T>> {
public:
  vector5() {}
  vector5(size_t a, size_t b, size_t c, size_t d, size_t e, T t = T())
      : vector<vector4<T>>(a, vector4<T>(b, c, d, e, t)) {}
};

#endif
#ifndef MOD_H
#define MOD_H

template <unsigned int N> class Field {
  typedef unsigned int ui;
  typedef unsigned long long ull;
  inline ui pow(ui a, ui p) {
    ui r = 1, e = a;
    while (p) {
      if (p & 1) {
        r = ((ull)r * e) % N;
      }
      e = ((ull)e * e) % N;
      p >>= 1;
    }
    return r;
  }
  /*extended GCD(slow):ll t=0,nt=1,r=N,nr=a;while(nr){ll
   * q=r/nr;t-=q*nt;swap(t,nt);r-=q*nr;swap(r,nr);}assert(r<=1);return(t<0)?t+N:t;*/
  inline ui inv(ui a) { return pow(a, N - 2); }

public:
  inline Field(int x = 0) : v(x < 0 ? N + x : x) {}
  inline Field<N> pow(int p) { return (*this) ^ p; }
  inline Field<N> operator^(int p) { return {(int)pow(v, (ui)p)}; }
  inline Field<N> &operator+=(const Field<N> &o) {
    if (v + o.v >= N)
      v += o.v - N;
    else
      v += o.v;
    return *this;
  }
  inline Field<N> &operator-=(const Field<N> &o) {
    if (v < o.v)
      v -= o.v - N;
    else
      v -= o.v;
    return *this;
  }
  inline Field<N> &operator*=(const Field<N> &o) {
    v = (ull)v * o.v % N;
    return *this;
  }
  inline Field<N> &operator/=(const Field<N> &o) { return *this *= inv(o.v); }
  inline Field<N> operator+(const Field<N> &o) const {
    Field<N> r{*this};
    return r += o;
  }
  inline Field<N> operator-(const Field<N> &o) const {
    Field<N> r{*this};
    return r -= o;
  }
  inline Field<N> operator*(const Field<N> &o) const {
    Field<N> r{*this};
    return r *= o;
  }
  inline Field<N> operator/(const Field<N> &o) const {
    Field<N> r{*this};
    return r /= o;
  }
  inline Field<N> operator-() {
    if (v)
      return {(int)(N - v)};
    else
      return {0};
  };
  inline Field<N> &operator++() {
    ++v;
    if (v == N)
      v = 0;
    return *this;
  }
  inline Field<N> operator++(int) {
    Field<N> r{*this};
    ++*this;
    return r;
  }
  inline Field<N> &operator--() {
    --v;
    if (v == -1)
      v = N - 1;
    return *this;
  }
  inline Field<N> operator--(int) {
    Field<N> r{*this};
    --*this;
    return r;
  }
  inline bool operator==(const Field<N> &o) const { return o.v == v; }
  inline bool operator!=(const Field<N> &o) const { return o.v != v; }
  inline explicit operator ui() const { return v; }
  inline static vector<Field<N>> fact(int t) {
    vector<Field<N>> F(t + 1, 1);
    for (int i = 2; i <= t; ++i) {
      F[i] = F[i - 1] * i;
    }
    return F;
  }
  inline static vector<Field<N>> invfact(int t) {
    vector<Field<N>> F(t + 1, 1);
    Field<N> X{1};
    for (int i = 2; i <= t; ++i) {
      X = X * i;
    }
    F[t] = 1 / X;
    for (int i = t - 1; i >= 2; --i) {
      F[i] = F[i + 1] * (i + 1);
    }
    return F;
  }

private:
  ui v;
};
template <unsigned int N> istream &operator>>(std::istream &is, Field<N> &f) {
  unsigned int v;
  is >> v;
  f = v;
  return is;
}
template <unsigned int N>
ostream &operator<<(std::ostream &os, const Field<N> &f) {
  return os << (unsigned int)f;
}
template <unsigned int N> Field<N> operator+(int i, const Field<N> &f) {
  return Field<N>(i) + f;
}
template <unsigned int N> Field<N> operator-(int i, const Field<N> &f) {
  return Field<N>(i) - f;
}
template <unsigned int N> Field<N> operator*(int i, const Field<N> &f) {
  return Field<N>(i) * f;
}
template <unsigned int N> Field<N> operator/(int i, const Field<N> &f) {
  return Field<N>(i) / f;
}

typedef Field<1000000007> FieldMod;

struct Ring {
  template <typename T> static T div(T p, T q, T N) {
    T t = 0, nt = 1, r = N, nr = q;
    while (nr != 0) {
      T q = r / nr;
      t -= q * nt;
      r -= q * nr;
      swap(t, nt);
      swap(r, nr);
    }
    t = (t < 0) ? t + N : t;
    r = (r < 0) ? r + N : r;
    if (gcd(p, N) % r != 0) {
      return 0;
    }
    return (t * p / r) % N;
  }
};
#endif

template <typename T> struct Fenwick {
  explicit Fenwick(ui N = 0, T t = T())
      : N(1u << logceil(N)), F(this->N, t), t(t) {}
  explicit Fenwick(const vector<T> &A, T t = T())
      : N(1u << logceil(A.size())), F(A), t(t) {
    F.resize(N);
    fill(F.begin() + A.size(), F.end(), t);
    for (int i = 0; i < N; i++) {
      int j = i + lsb(i + 1);
      if (j < N)
        F[j] += F[i];
    }
  }
  void add(int i, T v) {
    while (i <= N) {
      F[i] += v;
      i += lsb(i + 1);
    }
  }
  T sum(int i) const {
    T sum(t);
    while (i) {
      sum += F[i - 1];
      i -= lsb(i);
    }
    return sum;
  }
  T range(int i, int j) const {
    j++;
    T s(t);
    while (j > i) {
      s += F[j - 1];
      j -= lsb(j);
    }
    while (i > j) {
      s -= F[i - 1];
      i -= lsb(i);
    }
    return s;
  }
  T get(int i) const { return range(i, i); }
  void set(int i, T v) { add(i, v - get(i)); }
  constexpr int lsb(int i) const { return i & -i; }
  ui N;
  vector<T> F;
  T t;
  int max_lower(T v) {
    // TODO: this returns suspicious results ...
    if (F[0] >= v)
      return -1;
    if (F[N - 1] < v)
      return N - 1;

    int x = 0;
    T a = t;
    for (int s = N >> 1; s > 0; s >>= 1)
      if (a + F[x + s - 1] < v) {
        a += F[x + s - 1];
        x += s;
      }
    return x;
  }
};

template <typename T> struct Fenwick2 {
  explicit Fenwick2(ui N = 0, T t = T())
      : N(1u << logceil(N)), F(this->N, this->N, t), t(t) {}
  //    explicit Fenwick2(const vector<vector<T>>&A, T
  //    t=T()):N(1u<<logceil(A.size())),F(A),t(t){
  //            F.resize(N);
  //            for (int i=0;i<A.size();++i) { F[i].resize(N);
  //            fill(F[i].begin()+A.size(),F[i].end(),t); } for (int
  //            i=A.size();i<N;++i) { F[i].resize(N);
  //            fill(F[i].begin(),F[i].end(),t); }
  //
  ////            for(int i=0;i<N;i++){int j=i+lsb(i+1);if(j<N)F[j]+=F[i];}
  //    }
  void add(int x, int y, T v) {
    while (x <= N) {
      int z = y;
      while (z <= N) {
        F[x][z] += v;
        z += lsb(z + 1);
      }
      x += lsb(x + 1);
    }
  }

  T sum(int x, int y) {
    T sum(t);
    while (x <= N) {
      int z = y;
      while (z <= N) {
        sum += F[x][z];
        z -= lsb(z + 1);
      }
      x -= lsb(x + 1);
    }
    return sum;
  }
  T range(int x1, int y1, int x2, int y2) {
    T ans = sum(x2, y2);
    if (x1)
      ans -= sum(x1 - 1, y2);
    if (y1)
      ans -= sum(x2, y1 - 1);
    if (x1 && y1)
      ans += sum(x1 - 1, y1 - 1);
    return ans;
  }
  constexpr int lsb(int i) const { return i & -i; }
  ui N;
  vector2<T> F;
  T t;
};

class DTwinBinaryTrees {
public:
  void solve(istream &cin, ostream &cout) {
    int H;
    cin >> H;
    int L = 1 << H >> 1;
    vector<int> P(L);
    cin >> P;
    for (int &p : P)
      --p;

    vector2<FieldMod> Z(H, L, 1);
    for (int i = 0; i < L; ++i) {
      int j = L + i;
      int h = H - 1;
      while (j != 1) {
        Z[h--][i] *= j;
        j /= 2;
      }
      for (int h = 1; h < H; ++h)
        Z[h][i] *= Z[h - 1][i];
    }
    //        cout << Z;

    vector<FieldMod> X(L, 1);
    for (int i = 0; i < L; ++i) {
      X[i] = Z[H - 1][i] * Z[H - 1][P[i]];
    }

    vector2<FieldMod> CONT(H, H, 0), CONT2(H, H, 0);
    FieldMod br = 0;
    //        for (int i = 0; i < L; ++i) {
    //            for (int j = 0; j < L; ++j) {
    //                if (j == i) continue;
    //                FieldMod cur = X[i] * X[j];
    //                int h = 0;
    //                for (int d = H-1; d > 0; --d) {
    //                    if (Z[d][P[i]] == Z[d][P[j]]) {
    //                        cur /= Z[d][P[i]] * Z[d-1][P[i]];
    //                        h = d;
    //                        break;
    //                    }
    //                }
    //
    //                cout << cur << endl;
    //
    //                for (int d = H-1; d >= 0; --d) {
    //                    if (Z[d][i] == Z[d][j]) {
    ////                        cout << Z[d][i] << ' ' << Z[max(0,d-1)][i] <<
    ///endl; /                        cout << cur / Z[d][i] * Z[max(0,d-1)][i]
    ///<< endl;
    //                        CONT2[d][h] += cur / Z[d][i] / Z[max(0,d-1)][i];
    //                        br += cur / Z[d][i] / Z[max(0,d-1)][i];
    //                        break;
    //                    }
    //                }
    //            }
    ////            break;
    //        }

    FieldMod ans = 0;
    Fenwick<FieldMod> F(L, 0);
    for (int h = 0; h < H - 1; ++h) {
      for (int a = 0; a < (1 << h); ++a) {
        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          F.add(P[s], X[s]);
          //                    cout << s << ' ';
        }
        //                cout << endl;

        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          for (int l = 0; l < H - 1; ++l) {
            int t = P[s] ^ (1 << l);
            int hi = t | ((1 << l) - 1);
            int lo = hi ^ ((1 << l) - 1);
            FieldMod ff = F.range(lo, hi);
            //                        if (s == 0) cerr << h << ' ' << s << ' '
            //                        << P[s] << ' ' << ff << ' ' << lo << ' '
            //                        << hi << ' ' << Z[H-2-l][P[s]] << ' ' <<
            //                        Z[max(H-3-l, 0)][P[s]] << ' ' << Z[h][s]
            //                        << ' ' << Z[max(h-1, 0)][s] << endl;
            ff *= X[s];
            ff /= Z[H - 2 - l][P[s]] * Z[max(H - 3 - l, 0)][P[s]];
            //                        cerr << ff << endl;
            //                        cerr << "her " << Z[h][s] * Z[max(h-1,
            //                        0)][s] << ' ' << ff / (Z[h][s] *
            //                        Z[max(h-1, 0)][s]) << endl; if (s == 0) {
            CONT[h][H - 2 - l] += ff / (Z[h][s] * Z[max(h - 1, 0)][s]);
            ans += ff / (Z[h][s] * Z[max(h - 1, 0)][s]);
            //                        }
            //                        cerr << ans << endl;
            if (h != 0) {
              ans -= ff / (Z[h - 1][s] * Z[max(h - 2, 0)][s]);
            }
            //                        for (int v = 0; v < h; ++v) {
            //                            ans -= ff / (Z[v][s] * Z[max(v-1,
            //                            0)][s]);
            //                        }
          }
        }

        for (int x = 0; x < (L >> h); ++x) {
          int s = (a << (H - 1 - h)) + x;
          F.add(P[s], -X[s]);
        }
      }
    }

    //        cout << CONT << CONT2;
    //        cout << br << endl;
    cout << ans / 2 << '\\n';
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  DTwinBinaryTrees solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}