Masha and a Beautiful Tree

传送门

题意:
一棵完全的二叉树,在这棵二叉树的最后一行,有一段序列,现在他给的这个序列是乱序的,你有一种操作,可以交换一个二叉树节点的左右两边的儿子,最后使得最后的序列是递增的,问最少的操作次数,如果不行的话就输出-1


思路:
首先,先如果去模拟这个过程,时间上不行,而且这个操作也十分难写,所以肯定不是去模拟这个操作,那肯定是可以从题目中推导出一些结论,然后根据这些结论来写代码

  • m如果是1直接0,如果不是1必须二进制分解只能出现一个1,这里可以用__builtin_popcount()来快速求
  • 因为最后是递增的,所以比如有8个叶子节点,4个4个分组,1, 2, 3, 4必须在一个组,5, 6, 7, 8必须在一个组,所以这里就要有一个快速判断了,可能这里就有结论,当时就是没想到,这里的结论就是,对于左右两端,假设左端的数字和为num1, 右端的数字和为num2, 那abs(num2 - num1) == k * k, 这里的k就是要交换节点和层数有关了,比如要交换4个4个,那k == 4, 以此类推,知道了这个规律,这个规律可以用前缀和来维护,就可以二分的取分治,然后求出答案,在分治的同时判断是否合法

结论:
如果一个地方时间复杂度可能超时,那很有可能是有结论的,通过这个结论就可以一步得出

点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);
#define endl '\n'
using namespace std;

typedef long long ll;
const int MAXN = 262144 + 10;
ll T, m, ans = 0;
ll p[MAXN];
ll sum[MAXN];
bool flag = true;

void init()
{
    ans = 0, flag = true;
    for (int i = 1; i <= m; ++i)
        sum[i] = 0;
}

void dfs(ll l, ll r, ll k)
{
    if (l == r)
        return ;
    if (r - l == 1)
    {
        if (abs(p[r] - p[l]) == 1)
        {
            if (p[r] < p[l])
                ++ans;
            return ;    
        }
        else
        {
            flag = false;
            return ;
        }
    }
    ll mid = (l + r) >> 1;
    ll head = sum[mid] - sum[l - 1];
    ll end = sum[r] - sum[mid];
    if (abs(end - head) == k * k)
    {
        if (end < head)
            ++ans;
        dfs(l, mid, k / 2);
        dfs(mid + 1, r, k / 2);   
    }
    else
    {
        flag = false;
        return ;
    }
}

int main()
{
    IOS; cin.tie(0), cout.tie(0);
    cin >> T;
    while (T--)
    {
        cin >> m;
        init();
        
        for (int i = 1; i <= m; ++i)
            cin >> p[i], sum[i] = sum[i - 1] + p[i];
        if (m == 1)
        {
            cout << "0" << endl;
            continue;
        }    
        if (m & 1 || __builtin_popcount(m) != 1)
        {
            cout << "-1" << endl;
            continue;
        }    
        dfs(1, m, m / 2);
        cout << (flag == true ? ans : -1) << endl;
    }
    return 0;
}

posted @   YUGUOTIANQING  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示