CF 826 --D. Masha and a Beautiful Tree

The girl named Masha was walking in the forest and found a complete binary tree of height n and a permutation p of length m=2^{n}.

A complete binary tree of height n is a rooted tree such that every vertex except the leaves has exactly two sons, and the length of the path from the root to any of the leaves is n. The picture below shows the complete binary tree for n=2.

A permutation is an array consisting of n different integers from 1 to n. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not (2 occurs twice), and [1,3,4] is also not a permutation (n=3, but there is 4 in the array).

Let's enumerate m leaves of this tree from left to right. The leaf with the number i contains the value pi (1≤i≤m).

For example, if n=2, p=[3,1,4,2], the tree will look like this:

Masha considers a tree beautiful if the values in its leaves are ordered from left to right in increasing order.

In one operation, Masha can choose any non-leaf vertex of the tree and swap its left and right sons (along with their subtrees).

For example, if Masha applies this operation to the root of the tree discussed above, it will take the following form:

 

 Help Masha understand if she can make a tree beautiful in a certain number of operations. If she can, then output the minimum number of operations to make the tree beautiful.

Input

The first line contains single integer t (1≤t≤10^4) — number of test cases.

In each test case, the first line contains an integer m (1≤m≤2621441), which is a power of two  — the size of the permutation p.

The second line contains m integers: p1,p2,…,pm(1≤pi≤m) — the permutation p.

It is guaranteed that the sum of m over all test cases does not exceed 3⋅10^5.

Output

For each test case in a separate line, print the minimum possible number of operations for which Masha will be able to make the tree beautiful or -1, if this is not possible.

Example

input

4
8
6 5 7 8 4 3 1 2
4
3 1 4 2
1
1
8
7 8 4 3 1 2 6 5

output

4
-1
0
-1

题意:完全二叉树,操作是可以左右反转子树,问至少操作多少次使得叶子是1~n从小到大排列。

解析:我们可以意识到如果某个子树中值不是一段连续值,其中缺失的值是无法通过反转子树来弥补,那么肯定就是无解的,这个我们让k从2开始到n把每一段子树的值取出来判断是否连续。

有解情况下,我们可以先从小的子树到大的子树,把每k个数的值取出来,表示一个子树下的值,如果发现不是单调递增,那么就是需要反转,注意,反转一次就break,因为我们是从小到大,最开始就2个点,然后4个点,所以到后面的子树如果发现不是单调递增,那么我们只需反转一次就可以使其变成有序的,每次循环出来将该子树的值更新有序即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N],n;
void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int k=2,ans=0;
    while(k<=n)//从小到大子树2,4,8....
    {
        for(int i=1;i<=n;i+=k)//每k个数是同一个子树
        {
            vector<int> v;
            for(int j=i;j<=i+k-1;j++) v.push_back(a[j]);
            sort(v.begin(), v.end());
            int x=0;
            for(int i=1;i<v.size();i++)//此循环判断是否不合法
            {
                if(v[i]!=v[i-1]+1)
                {
                    printf("-1\n");
                    return;
                }
            }
            for(int j=i;j<=i+k-1;j++)//跟有序值比较
            {
                if(a[j]!=v[x])//如果不是有序的,那么需要反转
                {
                    ans++;
                    break;
                }
                x++;
            }
            x=0;
            for(int j=i;j<=i+k-1;j++) a[j]=v[x++];//覆盖更新
        }
        k*=2;
    }
    printf("%d\n",ans);
}
int main()
{
    int t=1;
    scanf("%d",&t);
    while(t--) solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值