Problem p02591 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(), x.end()
#define L(i, u) for (register int i = head[u]; i; i = nxt[i])
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)
#define per(i, a, b) for (register int i = (a); i >= (b); i--)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
typedef vector<int> Vi;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T> T gcd(T a, T b) { return !b ? a : gcd(b, a % b); }
template <class T> inline void umin(T &x, T y) { x = x < y ? x : y; }
template <class T> inline void umax(T &x, T y) { x = x > y ? x : y; }
mt19937 R(chrono::system_clock().now().time_since_epoch().count());

const int N = 1 << 20 | 3, mo = 1e9 + 7;
inline void add(int &x, int y) { x = x + y < mo ? x + y : x + y - mo; }
inline void sub(int &x, int y) { x = x - y >= 0 ? x - y : x - y + mo; }
inline int power(int a, int n) {
  int res = 1;
  while (n) {
    if (n & 1)
      res = 1LL * res * a % mo;
    a = 1LL * a * a % mo;
    n >>= 1;
  }
  return res;
}
int h, p[N], q[N], dy[N], rev[N], val[N], ival[N], inv[N], le[N], ri[N];
inline int lowbit(int x) { return x & -x; }
inline int getlca(int x, int y) { return x >> (h - dy[lowbit(rev[x ^ y])]); }
inline int calc(int x, int y) {
  int z = getlca(x, y);
  return 1ll * val[x] * val[y] % mo * ival[z] % mo * ival[z >> 1] % mo;
}
int xs[N], zhi[N][8], tot, res;
struct node {
  int id, l, r, pos, xs;
};
vector<node> que[N];
int v[N], bas;
inline void ins(int p, int x) {
  assert(p <= (1 << h - 1) && p);
  while (p <= (1 << h - 1))
    add(v[p], x), p += p & -p;
}
int qry(int p) {
  assert(p <= (1 << h - 1));
  int r = 0;
  while (p)
    add(r, v[p]), p -= p & -p;
  return r;
}
int debug(int l1, int r1, int l2, int r2) {
  int res = 0;
  rep(i, l1, r1) if (p[i - bas] + bas >= l2 && p[i - bas] + bas <= r2) res =
      (res + 1ll * val[i] * val[p[i - bas] + bas]) % mo;
  return res;
}
int main() {
  freopen("1.in", "r", stdin);
  read(h);
  rep(i, 1, 1 << h - 1) read(p[i]), q[p[i]] = i;
  int B = h >> 1;
  bas = (1 << h - 1) - 1;
  rep(i, 0, (1 << h) - 1) rep(j, 0, h - 1) if (i >> j & 1) rev[i] |=
      1 << h - 1 - j;
  rep(i, 0, h - 1) dy[1 << i] = i;
  val[0] = 1;
  val[1] = 1;
  rep(i, 2, (1 << h) - 1) val[i] = 1ll * val[i >> 1] * i % mo;
  rep(i, 0, (1 << h) - 1) inv[i] = power(i, mo - 2),
                          ival[i] = power(val[i], mo - 2);
  assert(ival[0] == 1 && ival[1] == 1);
  rep(i, 1 << h - 1,
      (1 << h) - 1) for (int j = i + 1;
                         j < (1 << h) && getlca(i, j) >= (1 << B); j++) {
    res = (res + 1ll * calc(i, j) * calc(p[i - bas] + bas, p[j - bas] + bas)) %
          mo;
    //	printf("%d %d : %d %d
    //%d\n",i,j,calc(i,j),calc(p[i-bas]+bas,p[j-bas]+bas),calc(i,j)*calc(p[i]+bas,p[j]+bas));
  }
  rep(i, 1 << h - 1,
      (1 << h) - 1) for (int j = i + 1;
                         j < (1 << h) && getlca(i, j) >= (1 << B);
                         j++) if (getlca(q[i - bas] + bas, q[j - bas] + bas) <
                                  (1 << B)) res =
      (res + 1ll * calc(i, j) * calc(q[i - bas] + bas, q[j - bas] + bas)) % mo;
  /*rep(i,1<<h-1,(1<<h)-1)for(int
  j=i+1;j<(1<<h);j++)if(getlca(i,j)>=(1<<B)||getlca(p[i-bas]+bas,p[j-bas]+bas)>=(1<<B)){
          res=(res+1ll*calc(i,j)*calc(p[i-bas]+bas,p[j-bas]+bas))%mo;
  }*/
  memset(le, 0x3f, sizeof(le));
  rep(i, 1 << h - 1, (1 << h) - 1) for (int j = i; j; j >>= 1) {
    umax(ri[j], i);
    umin(le[j], i);
  }
  rep(x, 1, (1 << B) - 1)
      rep(y, 1, (1 << B) - 1) if ((x << 1) < (1 << h) && (y << 1) < (1 << h)) {
    xs[++tot] = (1ll * ival[x] * ival[x >> 1] % mo) *
                (1ll * ival[y] * ival[y >> 1] % mo) % mo;
    que[le[x * 2] - 1].pb((node){tot, le[y * 2], ri[y * 2], 0, -1});
    que[ri[x * 2]].pb((node){tot, le[y * 2], ri[y * 2], 0, 1});
    que[le[x * 2 + 1] - 1].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 1, -1});
    que[ri[x * 2 + 1]].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 1, 1});
    que[le[x * 2] - 1].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 2, -1});
    que[ri[x * 2]].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 2, 1});
    que[le[x * 2 + 1] - 1].pb((node){tot, le[y * 2], ri[y * 2], 3, -1});
    que[ri[x * 2 + 1]].pb((node){tot, le[y * 2], ri[y * 2], 3, 1});
  }
  rep(i, 1 << h - 1, (1 << h) - 1) {
    ins(p[i - bas], 1ll * val[i] * val[p[i - bas] + bas] % mo);
    //	cerr<<1ll*val[i]*val[p[i-bas]+bas]%mo<<endl;
    for (auto q : que[i])
      (zhi[q.id][q.pos] +=
       1ll * q.xs * (qry(q.r - bas) - qry(q.l - bas - 1))) %= mo;
  }
  //	cerr<<debug(le[2],ri[2],le[2],ri[2])<<endl;
  //	cerr<<debug(le[3],ri[3],le[3],ri[3])<<endl;
  //	cerr<<debug(le[2],ri[2],le[3],ri[3])<<endl;
  //	cerr<<debug(le[3],ri[3],le[2],ri[2])<<endl;
  rep(i, 1, tot) {
    //	rep(j,0,7)
    res = (res +
           1ll * (1ll * zhi[i][0] * zhi[i][1] + 1ll * zhi[i][2] * zhi[i][3]) %
               mo * xs[i]) %
          mo;
    //	printf("%d:%d %d %d %d
    //%d\n",i,zhi[i][0],zhi[i][1],zhi[i][2],zhi[i][3],xs[i]);
  }
  res = (res + mo) % mo;
  cout << res << endl;
  //	cerr<<getlca(4,7)<<endl;
  //	rep(i,4,7)rep(j,i+1,7)printf("%d %d:%d %d\n",i,j,getlca(i,j),calc(i,j));
  //	cerr<<getlca(4,5)<<endl;
  //	cerr<<getlca(8,9)<<endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(), x.end()
#define L(i, u) for (register int i = head[u]; i; i = nxt[i])
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)
#define per(i, a, b) for (register int i = (a); i >= (b); i--)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
typedef vector<int> Vi;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T> T gcd(T a, T b) { return !b ? a : gcd(b, a % b); }
template <class T> inline void umin(T &x, T y) { x = x < y ? x : y; }
template <class T> inline void umax(T &x, T y) { x = x > y ? x : y; }
mt19937 R(chrono::system_clock().now().time_since_epoch().count());

const int N = 1 << 20 | 3, mo = 1e9 + 7;
inline void add(int &x, int y) { x = x + y < mo ? x + y : x + y - mo; }
inline void sub(int &x, int y) { x = x - y >= 0 ? x - y : x - y + mo; }
inline int power(int a, int n) {
  int res = 1;
  while (n) {
    if (n & 1)
      res = 1LL * res * a % mo;
    a = 1LL * a * a % mo;
    n >>= 1;
  }
  return res;
}
int h, p[N], q[N], dy[N], rev[N], val[N], ival[N], inv[N], le[N], ri[N];
inline int lowbit(int x) { return x & -x; }
inline int getlca(int x, int y) { return x >> (h - dy[lowbit(rev[x ^ y])]); }
inline int calc(int x, int y) {
  int z = getlca(x, y);
  return 1ll * val[x] * val[y] % mo * ival[z] % mo * ival[z >> 1] % mo;
}
int xs[N], zhi[N][8], tot, res;
struct node {
  int id, l, r, pos, xs;
};
vector<node> que[N];
int v[N], bas;
inline void ins(int p, int x) {
  assert(p <= (1 << h - 1) && p);
  while (p <= (1 << h - 1))
    add(v[p], x), p += p & -p;
}
int qry(int p) {
  assert(p <= (1 << h - 1));
  int r = 0;
  while (p)
    add(r, v[p]), p -= p & -p;
  return r;
}
int debug(int l1, int r1, int l2, int r2) {
  int res = 0;
  rep(i, l1, r1) if (p[i - bas] + bas >= l2 && p[i - bas] + bas <= r2) res =
      (res + 1ll * val[i] * val[p[i - bas] + bas]) % mo;
  return res;
}
int main() {
  read(h);
  rep(i, 1, 1 << h - 1) read(p[i]), q[p[i]] = i;
  int B = h >> 1;
  bas = (1 << h - 1) - 1;
  rep(i, 0, (1 << h) - 1) rep(j, 0, h - 1) if (i >> j & 1) rev[i] |=
      1 << h - 1 - j;
  rep(i, 0, h - 1) dy[1 << i] = i;
  val[0] = 1;
  val[1] = 1;
  rep(i, 2, (1 << h) - 1) val[i] = 1ll * val[i >> 1] * i % mo;
  rep(i, 0, (1 << h) - 1) inv[i] = power(i, mo - 2),
                          ival[i] = power(val[i], mo - 2);
  assert(ival[0] == 1 && ival[1] == 1);
  rep(i, 1 << h - 1,
      (1 << h) - 1) for (int j = i + 1;
                         j < (1 << h) && getlca(i, j) >= (1 << B); j++) {
    res = (res + 1ll * calc(i, j) * calc(p[i - bas] + bas, p[j - bas] + bas)) %
          mo;
    //	printf("%d %d : %d %d
    //%d\n",i,j,calc(i,j),calc(p[i-bas]+bas,p[j-bas]+bas),calc(i,j)*calc(p[i]+bas,p[j]+bas));
  }
  rep(i, 1 << h - 1,
      (1 << h) - 1) for (int j = i + 1;
                         j < (1 << h) && getlca(i, j) >= (1 << B);
                         j++) if (getlca(q[i - bas] + bas, q[j - bas] + bas) <
                                  (1 << B)) res =
      (res + 1ll * calc(i, j) * calc(q[i - bas] + bas, q[j - bas] + bas)) % mo;
  /*rep(i,1<<h-1,(1<<h)-1)for(int
  j=i+1;j<(1<<h);j++)if(getlca(i,j)>=(1<<B)||getlca(p[i-bas]+bas,p[j-bas]+bas)>=(1<<B)){
          res=(res+1ll*calc(i,j)*calc(p[i-bas]+bas,p[j-bas]+bas))%mo;
  }*/
  memset(le, 0x3f, sizeof(le));
  rep(i, 1 << h - 1, (1 << h) - 1) for (int j = i; j; j >>= 1) {
    umax(ri[j], i);
    umin(le[j], i);
  }
  rep(x, 1, (1 << B) - 1)
      rep(y, 1, (1 << B) - 1) if ((x << 1) < (1 << h) && (y << 1) < (1 << h)) {
    xs[++tot] = (1ll * ival[x] * ival[x >> 1] % mo) *
                (1ll * ival[y] * ival[y >> 1] % mo) % mo;
    que[le[x * 2] - 1].pb((node){tot, le[y * 2], ri[y * 2], 0, -1});
    que[ri[x * 2]].pb((node){tot, le[y * 2], ri[y * 2], 0, 1});
    que[le[x * 2 + 1] - 1].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 1, -1});
    que[ri[x * 2 + 1]].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 1, 1});
    que[le[x * 2] - 1].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 2, -1});
    que[ri[x * 2]].pb((node){tot, le[y * 2 + 1], ri[y * 2 + 1], 2, 1});
    que[le[x * 2 + 1] - 1].pb((node){tot, le[y * 2], ri[y * 2], 3, -1});
    que[ri[x * 2 + 1]].pb((node){tot, le[y * 2], ri[y * 2], 3, 1});
  }
  rep(i, 1 << h - 1, (1 << h) - 1) {
    ins(p[i - bas], 1ll * val[i] * val[p[i - bas] + bas] % mo);
    //	cerr<<1ll*val[i]*val[p[i-bas]+bas]%mo<<endl;
    for (auto q : que[i])
      (zhi[q.id][q.pos] +=
       1ll * q.xs * (qry(q.r - bas) - qry(q.l - bas - 1))) %= mo;
  }
  //	cerr<<debug(le[2],ri[2],le[2],ri[2])<<endl;
  //	cerr<<debug(le[3],ri[3],le[3],ri[3])<<endl;
  //	cerr<<debug(le[2],ri[2],le[3],ri[3])<<endl;
  //	cerr<<debug(le[3],ri[3],le[2],ri[2])<<endl;
  rep(i, 1, tot) {
    //	rep(j,0,7)
    res = (res +
           1ll * (1ll * zhi[i][0] * zhi[i][1] + 1ll * zhi[i][2] * zhi[i][3]) %
               mo * xs[i]) %
          mo;
    //	printf("%d:%d %d %d %d
    //%d\n",i,zhi[i][0],zhi[i][1],zhi[i][2],zhi[i][3],xs[i]);
  }
  res = (res + mo) % mo;
  cout << res << endl;
  //	cerr<<getlca(4,7)<<endl;
  //	rep(i,4,7)rep(j,i+1,7)printf("%d %d:%d %d\n",i,j,getlca(i,j),calc(i,j));
  //	cerr<<getlca(4,5)<<endl;
  //	cerr<<getlca(8,9)<<endl;
  return 0;
}