1 条题解

  • 0
    @ 2026-5-16 22:24:44

    题解:E. And Constraint

    题目理解

    我们有两个序列:

    • a1,a2,,an1a_1, a_2, \dots, a_{n-1}(长度 n1n-1
    • b1,b2,,bnb_1, b_2, \dots, b_n(长度 nn

    可以进行的操作:每次选择任意 bib_i 增加 11,花费 11 次操作。

    目标:用最少操作次数使得对所有 1in11 \le i \le n-1 满足:

    bi & bi+1=aib_i \ \&\ b_{i+1} = a_i

    其中 &\& 是按位与运算。如果不可能,输出 1-1


    核心难点

    1. 操作只能增加 bib_i,不能减少。所以初始 bib_i 是下界。
    2. 约束 bi&bi+1=aib_i \& b_{i+1} = a_i位级约束
    3. 操作次数最小化 = 让 bib_i 尽量小,但又必须满足所有与约束。

    位运算性质

    对任意两个数 x,yx, y

    $$x \& y = z \quad \Rightarrow \quad z \le x \text{ 且 } z \le y $$

    并且 zz 的二进制位必须是 xxyy 都有的位。

    更关键:若 x&y=zx \& y = z,则:

    • zz 的某一位是 11,则 xxyy 的这一位都必须是 11
    • zz 的某一位是 00,则 xxyy 不能同时在这一位为 11(可以一个 11 一个 00,或两个 00)。

    动态规划思路

    标程使用了按位构造的 DP

    状态定义

    fif_i 表示:在考虑前 iibb 值且满足前 i1i-1 个与约束后,bib_i 可能取的值以及达到该值的最少操作数。

    bib_i 范围很大(<229<2^{29}),不能直接枚举。标程技巧:
    只枚举 bib_i 可能的值,这些值由 ai1a_{i-1}aia_ibib_i 的初始值决定


    关键观察

    固定 bib_ibi+1b_{i+1} 需要满足:

    bi&bi+1=aib_i \& b_{i+1} = a_i bi+1&bi+2=ai+1b_{i+1} \& b_{i+2} = a_{i+1}

    对于 bi+1b_{i+1},它必须同时满足:

    1. bib_i 的与等于 aia_i
    2. bi+2b_{i+2} 的与等于 ai+1a_{i+1}

    所以 bi+1b_{i+1} 的二进制位受两个方向约束。

    标程采用了从左到右递推,每个 bib_i 只依赖于 ai1a_{i-1}aia_i


    转移方法

    标程中的核心循环:

    for(int i=1;i<=n;i++){
        int x=0;
        g.clear();
        for(int j=30;j>=-1;j--){
            int y = x | a[i-1] | a[i];
            if(j!=-1) y |= (1<<j); 
            if(y >= b[i]){
                ll mn=inf;
                for(stu l:f){
                    if((l.x & y) != a[i-1]) continue;
                    mn = min(mn, l.dp + y - b[i]);
                }
                if(mn<inf) g.push_back((stu){y,mn});
            }
            x |= ((1<<j) & b[i]);
        }
        swap(f,g);
    }
    

    解释

    • xx:当前已经确定必须为 11 的位(来源于 bib_i 的初始值)。

    • 从高位到低位(j=30j=30j=1j=-1)枚举:

      • 尝试在 yy 中设置或不设置这位(当 j=1j=-1 时表示不设置任何新位)。
      • yy 必须包含 ai1a_{i-1}aia_i 的所有 11 位(因为 bi1&bi=ai1b_{i-1}\&b_i = a_{i-1}bi&bi+1=aib_i\&b_{i+1}=a_i 都要求 bib_i 在这些位为 11)。
      • 如果 yb[i]y \ge b[i](不能减少,只能增加),则 yy 是一个可能的 bib_i 新值。
      • 从上一层的 ff 中找出所有 bi1b_{i-1}l.xl.x 满足 l.x&y=ai1l.x \& y = a_{i-1},计算操作数增量 yb[i]y - b[i],取最小值。
      • 加入 gg 作为这一层的可能状态。
    • xx 逐步累加 b[i]b[i] 的当前位,确保我们考虑了所有可能的 yy


    为什么这样枚举是充分的?

    因为 bib_i 只能从初始值 b[i]b[i] 开始增加,且增加的位只能从 0011
    所有可能达到的 bib_i 必须是:

    $$b_i \ge b[i] \quad \text{且} \quad b_i \ \&\ a_{i-1} = a_{i-1} \ \text{且} \ b_i \ \&\ a_i = a_i $$

    bib_i 必须包含 ai1a_{i-1}aia_i 的所有 11 位。

    标程中的枚举方式,从高位到低位尝试设置 0011,覆盖了所有满足 bib[i]b_i \ge b[i] 且包含 ai1aia_{i-1} | a_i 所有 11 位的值。


    初始化和最终答案

    • 初始 ff 只有一个状态:b0b_000(虚拟前驱),操作数 00。但注意第一个约束是 b1&b2=a1b_1 \& b_2 = a_1,所以 b1b_1 需要包含 a1a_1
    • 最终 i=ni=n 时,ff 中存储所有可能的 bnb_n 值及其最小操作数。取最小 dpdp 值即为答案。
    • ff 为空,输出 1-1

    复杂度分析

    • 每个位置最多枚举约 31×231 \times 2yyjj30301-1,共 3232 次)。
    • 每次需要遍历上一层的 ff 大小,但 ff 大小不会超过 3232(因为每个 yy 都不同且数量有限)。
    • 总复杂度:O(n322)=O(1024n)O(n \cdot 32^2) = O(1024n),对于 n105n \le 10^5 可接受。

    样例验证

    以第一个样例为例:

    n=4
    a=[1,4,4]
    b=[1,2,3,4]
    

    过程:

    • b1b_1 可能值:包含 a1=1a_1=11\ge 1,最小为 11
    • b2b_2 需要包含 a1a2=14=5a_1|a_2=1|4=5,且 2\ge 2,并满足 b1&b2=1b_1\&b_2=1。尝试得 b2=5b_2=5 是可行且最小的,操作数 52=35-2=3
    • 继续推导得 b3=4b_3=4b4=4b_4=4,总操作数 3+1=43+1=4

    代码实现要点

    • 用结构体 stu{int x; ll dp;} 存储状态。
    • ana_n 设置为 00 以统一处理边界。
    • 使用 inf 表示不可达。
    • 注意位运算优先级。

    总结

    本题的关键在于:

    1. 利用按位与的约束bib_i 的可行值限制在较小的集合中。
    2. 从高位到低位贪心枚举 bib_i 的可能取值。
    3. 动态规划记录每个位置每种取值的最小操作数
    4. 由于位数 <29<29,状态数 O(32)O(32),复杂度可行。

    这是一个巧妙的按位构造 + DP 的题目,适合练习位运算与状态压缩思想。

    • 1

    信息

    ID
    7134
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    1
    已通过
    1
    上传者