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<iostream>
#include<iomanip>
#include<cassert>
#include<stdexcept>
#include<utility>
#include<functional>
#include<numeric>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<array>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<complex>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<bitset>
#include<memory>
using namespace std;
using ll=long long;

const ll MOD = 1e9+7;

struct Node {
    int left,right;
    ll val;
};

const int SZ = 5e7;
int sz = 0;
Node nodes[SZ];

int newNode(){
    nodes[sz] = Node{-1,-1,0};
    return sz++;
}

int idOf(int i){
    if(i==-1){
        return newNode();
    }
    else{
        return i;
    }
}

Node& ithNode(int i){
    assert(i>=1);
    return nodes[i];
}

int h;

ll addImpl(Node& node,int id,ll w,int v,int l,int r){
    if(r-l==1){
        node.val=(node.val+w*v)%MOD;
        return w*v%MOD;
    }
    else{
        int mid = (l+r)/2;
        int i,piyo;
        if(id<mid) i = node.left = idOf(node.left),r=mid,piyo=0;
        else i = node.right = idOf(node.right),l=mid,piyo=1;
        Node& chi = ithNode(i);
        ll ret = addImpl(chi,id,w,v*2+piyo,l,r);
        node.val=(node.val+ret*v)%MOD;
        return ret*v%MOD;
    }
}
void add(Node& node,int id,ll w){
    addImpl(node,id,w,1,0,1<<(h-1));
}

ll calcImpl(Node& node,int i,int dep,int l,int r,const vector<ll>& wei){
    if(i<l){
        return node.val*wei[dep]%MOD;
    }
    else if(r<=i+1){
        return 0;
    }
    else{
        int mid = (l+r)/2;
        ll ansl = node.left>0 ? calcImpl(ithNode(node.left),i,dep+1,l,mid,wei) : 0LL;
        ll ansr = node.right>0 ? calcImpl(ithNode(node.right),i,dep+1,mid,r,wei) : 0LL;
        return (ansl+ansr)%MOD;
    }
    
}
ll calc(Node& node,int i,const vector<ll>& wei){
    return calcImpl(node,i,0,0,1<<(h-1),wei);
}

int main(){
    cin>>h;
    int l = 1<<(h-1);
    vector<int> p(l);
    for(int i=0;i<l;i++) cin>>p[i];
    
    
    // build
    for(int i=0;i<(1<<h);i++) newNode();

    for(int i=0;i<l;i++){
        int x = i+l;
        int y = l+p[i]-1;
        int z = y;

        ll w = 1;
        while(z>1){
            w=w*z%MOD;
            Node& node = ithNode(z);
            add(node,i,w);
            z/=2;
        }
    }

    // answer
    ll ans = 0;
    for(int i=0;i<l;i++){
        int x = i+l;
        int y = l+p[i]-1;
        int z = y;
        ll w = z;
        vector<ll> ws(h+1);
        ws[h] = x;
        int tmp = x/2;
        for(int i=h-1;i>=0;i--) ws[i] = ws[i+1]*tmp%MOD,tmp/=2;

        while(z>1){
            w= (w*(z/2))%MOD;
            ll sc = calc(ithNode(z^1),i,ws);

            ans = (ans+w*sc)%MOD;
            z/=2;
        }        
    }

    cout<<ans<<endl;
    return 0;
}