Problem:
Score : 1000 points

Problem Statement

Inspired by the tv series Stranger Things, bear Limak is going for a walk between two mirror worlds.

There are two perfect binary trees of height H,
each with the standard numeration of vertices from 1 to 2^H-1.
The root is 1 and the children of x are 2 \cdot x and 2 \cdot x + 1.

Let L denote the number of leaves in a single tree, L = 2^{H-1}.

You are given a permutation P_1, P_2, \ldots, P_L of numbers 1 through L.
It describes L special edges that connect leaves of the two trees.
There is a special edge between vertex L+i-1 in the first tree and vertex L+P_i-1 in the second tree.

drawing for the first sample test, permutation P = (2, 3, 1, 4), special edges in green

Let's define product of a cycle as the product of numbers in its vertices.
Compute the sum of products of all simple cycles that have exactly two special edges, modulo (10^9+7).

A simple cycle is a cycle of length at least 3, without repeated vertices or edges.

Constraints

2 \leq H \leq 18

1 \leq P_i \leq L where L = 2^{H-1}

P_i \neq P_j (so this is a permutation)

Input

Input is given from Standard Input in the following format (where L = 2^{H-1}).

H
P_1 P_2 \cdots P_L

Output

Compute the sum of products of simple cycles that have exactly two special edges.
Print the answer modulo (10^9+7).

Sample Input 1

3
2 3 1 4

Sample Output 1

121788

The following drawings show two valid cycles (but there are more!) with products
2 \cdot 5 \cdot 6 \cdot 3 \cdot 1 \cdot 2 \cdot 5 \cdot 4 = 7200
and 1 \cdot 3 \cdot 7 \cdot 7 \cdot 3 \cdot 1 \cdot 2 \cdot 5 \cdot 4 \cdot 2 = 35280.
The third cycle is invalid because it doesn't have exactly two special edges.

Sample Input 2

2
1 2

Sample Output 2

36

The only simple cycle in the graph indeed has two special edges, and the product of vertices is
1 \cdot 3 \cdot 3 \cdot 1 \cdot 2 \cdot 2 = 36.

Sample Input 3

5
6 14 15 7 12 16 5 4 11 9 3 10 8 2 13 1

Sample Output 3

10199246

Solution in C++ (GCC 9.2.1) (judge verdict: Time Limit Exceeded)


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


#define PR(a, n) {cerr << #a << " = "; for (int _=1; _<=n; ++_) cerr << a[_] <<' '; cerr << '\n';}
#define PR0(a, n) {cerr << #a << " = "; for (int _=0; _<n; ++_) cerr << a[_] <<' '; cerr << '\n';}
#define db(x) {cerr << #x << " = " << x << '\n';}
#define FILE_NAME "data"


const int MAXN = 1<<19;
const int MAXH = 19;
const int MOD = 1e9 + 7;


int n, h, p[MAXN];
int64_t f[MAXN][MAXH + 2];
map<pair<int, int>, int64_t> sum;


int main() {
    #ifdef ACM
        freopen(FILE_NAME".in", "r", stdin);
    #endif

    cin >> h;
    n = 1 << (h - 1);

    for (int i = 0; i < n; ++i) {
        cin >> p[i];
        p[i] += n - 1;
    }

    for (int u = 1; u < (1<<h); ++u) {
        f[u][0] = u;
        for (int lu = 1; lu <= h; ++lu) {
            f[u][lu] = f[u / 2][lu - 1] * u % MOD;
        }
    }

    int64_t res = 0;
    for (int u = n; u < 2 * n; ++u) {
        int v = p[u - n];

        int branch_u = u % 2;
        for (int lu = 1, pu = u / 2; pu > 0; pu /= 2, ++lu) {
            int branch_v = v % 2;
            for (int lv = 1, pv = v / 2; pv > 0; pv /= 2, ++lv) {
                int64_t tmp = sum[make_pair(pu * 2 + 1 - branch_u,
                                            pv * 2 + 1 - branch_v)];
                (res += f[u][lu] * f[v][lv] % MOD * tmp) %= MOD;
                // if(u == 6)
                //     cerr << pv << ' ' << branch_v << '\n';
                if (u == 6 && v == 4 && pu == 1 && pv == 2) {
                    // cerr << v << ' ' << pu << ' ' << pv << '\n';
                    // cerr << u << ' ' << v << ' ' << pu << ' ' << pv << ' ' << f[u][lu] * f[v][lv] * tmp << '\n';
                    // cerr << pu * 2 + 1 - branch_u << ' ' << pv * 2 + 1 - branch_v << '\n';
                }
                // cerr << u << ' ' << v << ' ' << pu << ' ' << pv << ' ' << f[u][lu] * f[v][lv] * tmp << '\n';
                branch_v = pv % 2;
            }
            branch_u = pu % 2;
        }

        for (int lu = 0, pu = u; pu > 0; pu /= 2, ++lu) {
            for (int lv = 0, pv = v; pv > 0; pv /= 2, ++lv) {
                (sum[make_pair(pu, pv)] += f[u][lu] * f[v][lv]) %= MOD;
            }
        }
    }

    cout << res << '\n';
}