证明:当 x≥15 时,均能通过分裂操作获得 x 根魔法棒

要严谨证明 “x≥15 时必然满足条件”,可通过 “分裂操作的数学本质”+“连续有效值的覆盖性” 两步推导,逻辑如下:

第一步:明确分裂操作的数学本质

每次分裂操作的核心是:将 1 根魔法棒替换为正平方数 k² 根(k 为正整数,如 1、4、9、16...)。

设原魔法棒数量为 x,分裂后数量为 y,则总数量变化公式为:

y = 原数量 - 1(移除被分裂的 1 根) + k²(新增 k² 根)

整理得:y = x + (k² - 1)

其中,(k² - 1) 是分裂操作带来的 “增量”。由于 k≥1,可能的增量包括:

  • k=1 时,增量 = 0(相当于不操作);
  • k=2 时,增量 = 4-1=3(最小非零增量);
  • k=3 时,增量 = 9-1=8;
  • k=4 时,增量 = 16-1=15;
  • 以此类推(增量随 k 增大而增大)。

关键结论:每次操作可给总数量增加 3、8、15 等固定值,其中最小的非零增量是 3

第二步:利用 “连续 3 个有效值” 覆盖所有后续数

假设存在 3 个连续的整数 a、a+1、a+2,且这 3 个数均能通过分裂获得(即 “有效值”),那么对任意 x≥a,都能通过以下逻辑覆盖:

  • 若 x = a + 3m(m 为非负整数):从 a 开始,执行 m 次 “增量 3” 的操作,即可得到 x;
  • 若 x = a + 1 + 3m:从 a+1 开始,执行 m 次 “增量 3” 的操作,即可得到 x;
  • 若 x = a + 2 + 3m:从 a+2 开始,执行 m 次 “增量 3” 的操作,即可得到 x。

简言之:只要找到 3 个连续的有效值,它们之后的所有数都会是有效值(因为最小增量 3 能覆盖所有余数为 0、1、2 的数)。

第三步:验证 15、16、17 是连续的有效值

通过 “逆向推理”(即判断 x 能否通过减去某个增量,得到已知的有效值),可验证 15、16、17 均为有效值:

  1. x=15:选择增量 8(对应 k=3,k²-1=8),则前序值为 15-8=7(7 是已知有效值,可由 4 根分裂 1 根为 4 根得到:4-1+4=7)→ 15 有效;
  2. x=16:选择增量 15(对应 k=4,k²-1=15),则前序值为 16-15=1(1 是初始值,必然有效)→ 16 有效;
  3. x=17:选择增量 8(对应 k=3),则前序值为 17-8=9(9 是已知有效值,可由 1 根直接分裂为 9 根得到)→ 17 有效。

最终结论

由于 15、16、17 是 3 个连续的有效值,结合 “最小增量 3 的覆盖性”,所有 x≥15 的数都能通过分裂操作获得。因此,只需单独判断 x≤14 的情况(其中仅 2、3、5、6、8、11、14 为无效值),x≥15 时直接输出 “Yes” 即可。

import java.io.*;
import java.util.*;

public class Main {
    // 存储无法获得的魔法棒数量
    private static final Set<Long> IMPOSSIBLE = new HashSet<>();
    
    static {
        // 经过分析,只有这些数值无法通过分裂操作获得
        IMPOSSIBLE.add(2L);
        IMPOSSIBLE.add(3L);
        IMPOSSIBLE.add(5L);
        IMPOSSIBLE.add(6L);
        IMPOSSIBLE.add(8L);
        IMPOSSIBLE.add(11L);
        IMPOSSIBLE.add(14L);
    }
    
    public static void main(String[] args) throws IOException {
        // 使用BufferedReader和BufferedWriter提高IO效率,应对大量测试数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        int T = Integer.parseInt(br.readLine());
        for (int i = 0; i < T; i++) {
            long x = Long.parseLong(br.readLine());
            if (IMPOSSIBLE.contains(x)) {
                bw.write("No\n");
            } else {
                bw.write("Yes\n");
            }
        }
        
        bw.flush();
        bw.close();
        br.close();
    }
}