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: Accepted)

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

#ifdef DEBUG
#define display(x) cerr << #x << " = " << x << endl;
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define display(x) {}
#define eprintf(...) do {} while(0)
#endif

template<typename T> bool chmin(T &a, const T &b) { return a > b ? a = b, true : false; }
template<typename T> bool chmax(T &a, const T &b) { return a < b ? a = b, true : false; }
template<typename T>
ostream& operator << (ostream& out, const vector<T> &v) {
	int n = v.size();
	out << "{";
	for(int i = 0; i < n; ++i) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "}";
}
template<typename A, typename B>
ostream& operator << (ostream& out, const pair<A, B> &v) {
	return out << "(" << v.first << ", " << v.second << ")";
}

typedef long long LL;

const int maxN = (1 << 18) + 5;
const LL P = 1000000007;
int n, h, p[maxN];

LL val[maxN];

LL prod = 1, sum = 0;
void mark(int u, LL coef) {
	coef = coef * u % P;
	if(u < n / 2) {
		mark(u * 2, coef);
		mark(u * 2 + 1, coef);
	} else {
		int x = p[u];
		while(x) {
			val[x] = (val[x] + coef) % P;
			coef = coef * x % P;
			x /= 2;
		}
	}
}
LL count(int u, LL coef) {
	coef = coef * u % P;
	if(u < n / 2) {
		return (count(u * 2, coef) + count(u * 2 + 1, coef)) % P;
	} else {
		int x = p[u];
		LL sum = 0, ref = 0;
		while(x) {
			// ref = ref * x % P;
			coef = coef * x % P;
			(sum += val[x] * coef - val[x] * coef % P * x % P * (x / 2)) %= P;
			// (ref += (val[x] * coef - ref) % P * x) %= P;
			x /= 2;
		}
		return (sum + P) % P;
	}
}
void unmark(int u) {
	if(u < n / 2) {
		unmark(u * 2);
		unmark(u * 2 + 1);
	} else {
		int x = p[u];
		while(x) {
			val[x] = 0;
			x /= 2;
		}
	}
}
LL ans = 0;
void dfs(int u) {
	if(u < n / 2) {
		mark(u * 2, u);
		(ans += count(u * 2 + 1, 1)) %= P;
		unmark(u * 2);
		dfs(u * 2);
		dfs(u * 2 + 1);
	}
}

int main() {
#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
#endif
	cin >> h;
	n = (1 << h);
	for(int i = n / 2; i < n; ++i) cin >> p[i], p[i] += n / 2 - 1;
	memset(val, 0, sizeof(val));
	dfs(1);
	cout << ans << '\n';
	return 0;
}