Tree II

链接:https://ac.nowcoder.com/acm/problem/207389
来源:牛客网

系统中有一棵n个点的完全k叉树,现给出它的BFS层序遍历序列a_ia
i

(即从根节点开始,每一层从左向右遍历),请你还原这棵树,并返回加密后的答案。
答案加密方法:所有边两个端点异或的和,即\sum\limits_{i=1}^{n-1}u_i\ xor\ v_i
i=1

n−1

u
i

xor v
i

,其中(u_i, v_i)(u
i

,v
i

)为一条树上的边。

下面给出完全二叉树的定义:若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k层所有的结点都连续集中在最左边。
请你根据这个定义进行适度推广,得到完全k叉树的含义。
示例1
输入
复制
2,[1,2,3,4,5]
返回值
复制
18
说明
树边为(1, 2), (1, 3), (2, 4), (2, 5),加密过程为(12)+(13)+(24)+(25),答案为18。

样例1构成的完全二叉树为:

示例2
输入
复制
3,[1,2,3,4,5]
返回值
复制
17
说明
树边为(1, 2), (1, 3), (1, 4), (2, 5),加密过程为(12)+(13)+(14)+(25),答案为17。

样例2构成的完全三叉树为:

备注:
数据满足:1\leq n,k\leq 10^5, 1\leq a_i\leq 10^91≤n,k≤10
5
,1≤a
i

≤10
9
这题在上一个赛季出现过类似的,只不过节点更多了,开始范围和结束范围变了。道理是一样的,子节点异或上根节点的值相加。bfs模拟一遍就好了,只是要注意子节点的起始和结束范围。我们多画几个就知道,子节点的范围是
(root x k)+k-2<=i<=(root x k)+1;
也就是根节点乘于k加上k-2到根节点乘于k+1.
然后用队列模拟一遍即可,需要注意的是vector下标从0开始的,需要减一对应其值。
还有一个方法是既然要求的是所有的子节点异或上根节点的值,我们直接遍历所有的根节点即可
BFS,DFS都不是我擅长的。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param k int整型 表示完全k叉树的叉数k
     * @param a int整型vector 表示这棵完全k叉树的Bfs遍历序列的结点编号
     * @return long长整型
     */
    #define ll long long
    long long tree2(int k, vector<int>& a) {
        // write code here
        ll sum=0;
        queue<ll>q;
        q.push(1);
        while(q.size())
        {
            ll t=q.front();
            q.pop();
            for(int i=t*k-k+2;i<=k*t+1&&i<=a.size();i++)
            {
                    ll ans=a[i-1]^a[t-1];
                    sum+=ans;
                    q.push(i);
            }
        }
        //for(int i=1;i<n;i++)
        //{
            //sum+=a[i]^a[(i-1)/k];//将所有根结点与它的叶子结点异或,并将结果相加,所以遍历叶子结点就ok,从1开始一直到最后一个,根节点为i-1/k,这样逆过来想就十分简单了
        //}
        return sum;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值