首页 > 试题广场 >

小红的二叉树

[编程题]小红的二叉树
  • 热度指数:5848 时间限制: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)
  • 还是得简单罗列一下怎么计算简单路径的几个例子
  • 深度 n=2
    • 树有 3 个节点:根节点 A,左叶子 B,右叶子 C。

    • 路径数:只有一条路径 BAC(以 A 为中心)。

    • 公式计算: 3215=325=1,结果正确。

  • 深度 n=3

    • 树有 7 个节点:根节点 A,第二层节点 B 和 C,第三层叶子节点 D、E、F、G。

    • 路径数:以每个内部节点为中心:

      • A(根):路径 BAC,贡献 1。

      • B(度数为 3):路径 ABDABEDBE,贡献 3。

      • C(度数为 3):路径 ACFACGFCG,贡献 3。

    • 总路径数: 1+3+3=7

    • 公式计算: 3225=345=7,结果正确。

  • 深度 n=4

    • 树有 15 个节点。

    • 公式计算: 3235=385=19

    • 验证:非叶子节点 7 个(根节点 1 个贡献 1,第 2 层节点 2 个各贡献 3,第 3 层节点 4 个各贡献 3),总路径数 1+23+43=19,正确。

  • 发表于 2026-02-01 11:04:49 回复(0)
    容易发现,假设已知n层满二叉树的2长度简单路径数量为Sn,那么第(n +1)层的满二叉树的2长度简单路径数量为2 * Sn + 5。
    因为(n + 1)层满二叉树的根节点的左右子树各自为一个n层满二叉树,同时根节点-第一层的一个节点-第二层的一个节点总共构成4个路径,还有根节点与第一层两个节点构成的1条路径,所以2长度的简单路径数量为2 * Sn + 4 + 1。
    由于直接幂运算可能会出现溢出,因此我们需要逐层运算,并且中间取模。
    #include <stdio.h>
    
    int main() {
        int n, res;
        scanf("%d", &n);
        if(1 >= n)
        {
            printf("0");
            return 0;
        }
        int magic_number = 1000000007;
        res = 1;
        for(int nn = 2; nn < n; nn ++)
        {
            res = (2 * res) % magic_number;
            res += 5;
            res %= magic_number;
        }
        printf("%d", res);
        return 0;
    }


    发表于 2026-01-08 00:19:20 回复(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)