1 条题解

  • 0
    @ 2025-10-21 11:51:46

    「SDOI / SXOI2022」进制转换 题解

    问题分析

    核心问题

    计算:

    i=1nxiya(i)zb(i)\sum_{i=1}^{n} x^{i} y^{a(i)} z^{b(i)}

    其中:

    • a(i)a(i)ii 的二进制数位和
    • b(i)b(i)ii 的三进制数位和
    • nn 可达 101310^{13}

    关键观察

    观察1:问题规模

    n1013n \leq 10^{13} 排除了直接枚举的可能性,必须使用数位DP或数学方法。

    观察2:双重进制特性

    • 二进制:数位长度约 log2n44\log_2 n \approx 44
    • 三进制:数位长度约 log3n27\log_3 n \approx 27

    观察3:乘积结构

    答案包含三个独立因子的乘积:

    • xix^i:与数值本身相关
    • ya(i)y^{a(i)}:与二进制数位和相关
    • zb(i)z^{b(i)}:与三进制数位和相关

    算法思路

    方法一:双重数位DP

    核心思想:同时进行二进制和三进制的数位DP。

    状态设计

    • pos_bin:二进制当前位数
    • pos_tern:三进制当前位数
    • sum_bin:二进制当前数位和
    • sum_tern:三进制当前数位和
    • tight_bin:二进制是否紧贴上界
    • tight_tern:三进制是否紧贴上界
    • prod:当前累积的 xiya(i)zb(i)x^i y^{a(i)} z^{b(i)} 乘积

    挑战:状态数过多,需要优化。

    方法二:分别处理再合并

    步骤

    1. 用二进制数位DP计算到每个二进制前缀的贡献
    2. 在三进制层面整合二进制信息
    3. 使用生成函数思想合并结果

    方法三:基于进制的数位DP

    关键洞察:由于二进制和三进制独立,可以:

    • 先枚举二进制表示
    • 对每个二进制模式,计算对应的三进制贡献
    • 使用记忆化搜索优化

    算法细节

    状态优化策略

    优化1:进制对齐

    由于二进制位数(~44)和三进制位数(~27)不同,可以:

    • 从高位开始同步处理
    • 当某个进制处理完时,该进制后续位均为0

    优化2:乘积分离

    将状态分解为:

    • 二进制部分:维护 xiya(i)x^i y^{a(i)}
    • 三进制部分:维护 zb(i)z^{b(i)} 最后在合适的时候合并

    优化3:模运算优化

    预处理 x,y,zx, y, z 的幂次,避免重复计算。

    记忆化设计

    使用哈希表存储状态:

    struct State {
        int pos_bin, pos_tern;
        int sum_bin, sum_tern;
        bool tight_bin, tight_tern;
        // 哈希函数和相等比较
    };
    

    特殊性质利用

    x=y=1x = y = 1 的情况(测试点4,5)

    问题简化为:

    i=1nzb(i)\sum_{i=1}^{n} z^{b(i)}

    只需考虑三进制数位和。

    y=1y = 1 的情况(测试点6,7)

    问题简化为:

    i=1nxizb(i)\sum_{i=1}^{n} x^{i} z^{b(i)}

    二进制数位和不再影响答案。

    复杂度分析

    状态数分析

    • 二进制位数:O(logn)O(\log n)
    • 三进制位数:O(logn)O(\log n)
    • 二进制数位和:O(logn)O(\log n)
    • 三进制数位和:O(logn)O(\log n)
    • 紧贴标志:O(1)O(1)

    理论状态数O(log4n)442×272106O(\log^4 n) \approx 44^2 \times 27^2 \approx 10^6 量级

    实际优化

    通过状态压缩和哈希,实际有效状态数可控制在 10510^5 量级。

    实现要点

    1. 进制转换:将 nn 转换为二进制和三进制表示
    2. DP初始化:从最高位开始,两个进制都处于紧贴状态
    3. 状态转移
      • 枚举二进制当前位的选择(0或1)
      • 枚举三进制当前位的选择(0,1,2)
      • 更新累积乘积和数位和
    4. 边界处理:处理两个进制位数不同的情况

    优化策略

    优化1:状态剪枝

    • 当二进制已不紧贴且三进制已不紧贴时,后续状态相同
    • 当累积乘积为0时提前返回

    优化2:预处理幂次

    预处理 xk,yk,zkx^k, y^k, z^k 对于所有可能的 kk

    优化3:对称性利用

    利用数位DP中的对称状态减少计算量。

    数学视角

    生成函数方法

    定义生成函数:

    F(X,Y,Z)=i=1nXiYa(i)Zb(i)F(X,Y,Z) = \sum_{i=1}^{n} X^i Y^{a(i)} Z^{b(i)}

    可以写成:

    F(X,Y,Z)=数位该数位的贡献F(X,Y,Z) = \prod_{\text{数位}} \text{该数位的贡献}

    但需要处理上界限制。

    总结

    本题的核心在于设计高效的双重数位DP,关键技巧包括:

    1. 状态设计:合理设计包含二进制和三进制信息的状态
    2. 乘积维护:在DP过程中动态维护 xiya(i)zb(i)x^i y^{a(i)} z^{b(i)} 的乘积
    3. 状态优化:通过剪枝和记忆化减少状态数
    4. 进制同步:协调处理不同进制的数位

    对于 n1013n \leq 10^{13} 的数据规模,基于双重数位DP的解法是可行的,关键在于精细的状态设计和优化。

    • 1

    信息

    ID
    3651
    时间
    1000ms
    内存
    512MiB
    难度
    9.5
    标签
    递交数
    4
    已通过
    1
    上传者