首页 > 试题广场 >

小红的二叉树

[编程题]小红的二叉树
  • 热度指数:5601 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1024M,其他语言2048M
  • 算法知识视频讲解
\hspace{15pt}小红想知道,深度为 n满二叉树^{\texttt{[1]}}有多少条长度为 2简单路径^{\texttt{[2]}}?由于答案可能很大,请将答案对 (10^9+7) 取模后输出。
\hspace{15pt}在本题中,两条简单路径所包含的点集不同时,被视为不同的。例如,路径 u-v 与路径 v-u 被视为相同的,因为它们均包含点 u 与点 v

\hspace{15pt}一棵深度为 h满二叉树^{\texttt{[1]}}由恰好 2^h-1 个节点组成,每一个节点要么是叶子节点,要么有 2 个儿子,并且全部叶子节点的深度均为 h
\hspace{15pt}简单路径^{\texttt{[2]}}是指这样一条路径,其经过的顶点和边互不相同。

输入描述:
\hspace{15pt}在一行上输入一个正整数 n \left(1 \leqq n \leqq 10^4\right) 代表满二叉树的深度。


输出描述:
\hspace{15pt}输出一个整数,代表深度为 n 的满二叉树中,长度为 2 的简单路径的数量。由于答案可能很大,请将答案对 (10^9+7) 取模后输出。
示例1

输入

1

输出

0

说明

\hspace{15pt}在这个样例中,深度为 1 的满二叉树只有 1 个节点,所以没有长度为 2 的简单路径。
示例2

输入

3

输出

7

说明

\hspace{15pt}在这个样例中,所给出的满二叉树如下图所示:

n=int(input())
if n==1:
    print(0)
else:
    print((3*2**(n-1)-5)%(10**9+7))

发表于 2025-03-08 14:19:12 回复(0)
#include <stdio.h>
const int MOD = 1000000007; // 定义模数,方便复用

int main() {
    int n;
    scanf("%d", &n);
    if (n <= 1) {
        printf("0\n");
    } else if (n == 2) {
        printf("1\n");
    } else {
        long long pow2 = 1; // 存储2^(n-1) mod MOD,初始为2^0=1
        // 循环计算2^(n-1),边乘边取模(避免溢出)
        for (int i = 1; i <= n-1; i++) {
            pow2 = (pow2 * 2) % MOD; // 关键:每乘一次就取模,防止超范围
        }
        long long result = (3 * pow2 - 5) % MOD;
        // 防止结果为负数(比如n很小的时候,虽然这里n≥3不会,但养成习惯)
        if (result < 0) result += MOD;
        printf("%lld\n", result); // long long用%lld输出
    }
    return 0;
}
发表于 2025-11-18 21:10:23 回复(0)
这题难点不同编程语言可能不同,C/C++的话主要难在大数计算处理上。
原理并不难:
首先简单路径包括从上到下走和跨越子树的V字形路径,所以
当h=1,total=0;当h=2,total=1;从h=2开始,每多一层,就多出(叶节点数+叶节点数/2)个简单路径数,即2^(h-1)+2^(h-2)=3*2^(h-2)个简单路径。当h>=3时,total=1+32^(k-2),k从3到h,根据等比数列公式,可推出total=3*2^(h-1)-5,h=2也适用。所以,
当h=1时,total=0
当h>=2时,total=3*2^(h-1)-5。
C/C++的难点在于用pow计算非常大的指数会失效,结果出错,所以只能用循环,每次乘以2的时候取模。注意由于最后还要乘以3,超出int上限,所以要么用long long计算2的幂次,要么初始值设为3。
完整AC代码如下
#include <iostream>
using namespace std;
const int MOD = 1e9 + 7;
long long big2Exp(int n) {
    long long ans = 1;
    for (int i = 0; i < n; i++)
        ans = (ans * 2) % MOD;
    return ans;
}
int main() {
    int h;
    cin >> h;
    if (h == 1) cout << 0;
    else cout << (3 * big2Exp(h - 1) - 5) % MOD;
}
发表于 2025-11-08 14:13:05 回复(0)
由于是全二叉树,以1号节点为中心处的路径有1条,最下面一层的节点的路径数都为0,中间的每个节点为中心时,路径数都是3;所以只要计算前 h-1 层的路径数,它们的总数为 2**(h-1)-1,第一个节点有1,其余有3,总数为:(2**(h-1)-1-1)*3+1

import sys

mod_value = int(1e9 + 7)
h = int(sys.stdin.readline().strip())
if h < 2:
    print(0)
else:
    m = (2 ** (h - 1) - 1)
    print(((m - 1) * 3 + 1) % mod_value)
发表于 2025-08-01 10:47:17 回复(0)
考规律题,重要的是要知道当二叉树高度>= 2时,路径总数s = 3 * pow(2 * 1.0, (n - 1) * 1.0) - 5。另外为防止数值溢出,收集i结果变量需要定为long型,且需要在每一次乘法后 % 1000000007,最后输出答案即可。
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        final long mod = 1000000007;
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            if (n == 1){
                System.out.println(0);
            } else{
                long res = 1;
                for (int i = 0; i < n - 1; i++){
                    res *= 2;
                    res %= mod;
                }
                long s  = (3 * res) % mod - 5;
                System.out.println(s);
            }
        }
    }
} 

发表于 2025-07-19 21:26:33 回复(0)
import java.util.Scanner; 
import java.math.BigInteger;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        BigInteger out = func(n);
        BigInteger seven = new BigInteger("7");
        BigInteger ten = new BigInteger("10");
        System.out.println(out.remainder(ten.pow(9).add(seven)));
    }

    private static BigInteger func(int level){
        if(level == 1) {
            return new BigInteger("0");
        } else if (level == 2) {
            return new BigInteger("1");
        } else {
            BigInteger two = new BigInteger("2");
            BigInteger three = new BigInteger("3");
            return three.multiply(two.pow(level-2)).add(func(level-1));
        }
    }
}

发表于 2025-06-28 10:16:41 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws IOException {
        // ((2^n - 1) * 3 -2 ) mod 100000007
        int base = 1000000007;
        long baseRemainder = (1 << 30) % base;
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int deep = Integer.parseInt(bufferedReader.readLine()) - 1;
        int len = deep / 30;
        int less = deep % 30;
        long remainder = 1;
        for (int i = 0; i < len; i++) {
            remainder = (remainder * baseRemainder) % base;
        }
        remainder = remainder * ((1L << less) % base);
        remainder = (remainder - 1) * 3 % base;
        System.out.println(remainder > 0 ? remainder - 2 : remainder);
    }
}
为啥我没想到用BigInteger呢
发表于 2025-05-31 00:35:50 回复(0)
 在这张图中,可以看出每次存在一个非页节点,就会有一条路径,每次存在一个高度为3的非叶子节点,就会有四条路径
故高度为3,可以计算出4+3*1种路径
#include <iostream>
using namespace std;

const int mod = 1e9+7;

unsigned long long Mypow(unsigned long long n, int m) {
    // 使用 unsigned long long 防止溢出
    for (int i = 1; i < m; ++i) {   // 执行 m-1 次左移
        n <<= 1;
        n %= mod;//每次移位都%一次,避免越界
    }
    return n;
}



int main() {
    int h;
    cin >> h;
    unsigned long long ans = 0;
    if (h > 1) {
        ans += (Mypow(2, h-1) - 1)%mod;  // 计算非叶子节点的贡献
    }
    if (h > 2) {
        ans += 4 * (Mypow(2, h-2) - 1)%mod;  // 计算高度为 2 节点的贡献
    }
    cout << ans % mod;  // 使用明确的模数
    return 0;
}

发表于 2025-04-26 19:44:58 回复(0)
深度为 n 的满二叉树中长度为 2 的简单路径数量的通用公式为 3×2n15n2),当 n=1 时,路径数量为 0。
#include <iostream>
#include <cmath>
using namespace std;

const int MOD = 1e9 + 7;

int main() {
    int n;
    cin >> n;

    if (n < 2) {
        cout << 0 << endl;
    } else {
        int ans = 3;
        for (int i = 0; i < n - 1; ++i) {
            ans = (ans * 2) % MOD;
        }
        ans = (ans - 5) % MOD;
        cout << ans << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")


发表于 2025-04-09 17:31:36 回复(0)
h=int(input())
if h<2:
    print(0)
else:
    res=1+6*(2**(h-2)-1)%(10**9+7)
    print(res)
啥啊这是
发表于 2025-04-09 09:44:11 回复(0)
//理解了还是挺简单的  为啥没人提交awa 很难吗??简易版

import java.math.BigInteger;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
//有俩个问题 一个是如何计算答案 并通过string方式存储   然后再以mod 取模方法 取出答案 输出
        int n = in.nextInt();
        if (n == 1) {
            System.out.println(0);
            return;
        } else {
            BigInteger a = new BigInteger("2");
            BigInteger c = new BigInteger("6");
            BigInteger e = new BigInteger("5");
            BigInteger moshu = new BigInteger("1000000007");
            BigInteger result = c.multiply(a.pow(n-2)).subtract(e).mod(moshu);
            System.out.println(result);
        }
    }
}

发表于 2025-04-06 14:59:39 回复(0)
import java.math.BigInteger;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        if (n == 1)
            System.out.println(0);
        else if (n == 2)
            System.out.println(1);
        else {
            // 计算:3 * pow(2, n-1) - 5
            BigInteger A = BigInteger.ONE.shiftLeft(n - 1)
                    .multiply(BigInteger.valueOf(3))
                    .subtract(BigInteger.valueOf(5));

            // 计算:pow(10, 9) + 7
            BigInteger B = BigInteger.TEN.pow(9)
                    .add(BigInteger.valueOf(7));

            System.out.println(A.mod(B));
        }
    }

}

发表于 2025-04-06 10:30:20 回复(0)
import sys
a=int(input())
if a==1:
    print(0)
else:print((2**a-4+2**(a-1)-1)%((10**9)+7))

发表于 2025-03-06 07:23:21 回复(0)
import sys
n = int(input())
result = 0
if n <= 1:
    result = 0
elif n == 2:
    result = 1
else:
    root = 1
    nodes = 2**(n) -1 -root - 2**(n-1)
    result = nodes * 3 + root
print(result%(10**9 + 7))


发表于 2025-03-05 21:57:58 回复(0)