1 条题解

  • 0
    @ 2026-5-18 19:18:58

    C. Bitwise Slides 详细题解

    问题理解

    我们有三个初始为 00 的变量 PPQQRR。按顺序处理数组 a1,a2,,ana_1, a_2, \dots, a_n,对于每个 aia_i,必须选择恰好一个变量进行异或操作(PPaiP \leftarrow P \oplus a_i 等)。

    主要规则:每次操作之后,PPQQRR 不能两两不同。即至少有两个数相等。

    问:有多少种操作序列满足该规则,答案对 109+710^9+7 取模。


    核心观察

    1. 异或运算的性质

    • x0=xx \oplus 0 = x
    • 异或满足交换律、结合律
    • 异或一个数两次回到原值

    2. 三个数相等的类型

    x=Px = Py=Qy = Qz=Rz = R
    “不能两两不同”意味着至少有两个相等,所以可能的类型有:

    • 类型 A:P=QRP = Q \neq R
    • 类型 B:P=RQP = R \neq Q
    • 类型 C:Q=RPQ = R \neq P
    • 类型 D:P=Q=RP = Q = R

    注意:所有数相等时,属于上述类型的“等号成立”情况。


    关键想法:考虑两两异或值

    定义:

    $$X = P \oplus Q,\quad Y = P \oplus R,\quad Z = Q \oplus R $$

    注意 XYZ=0X \oplus Y \oplus Z = 0(因为 $X \oplus Y = (P\oplus Q) \oplus (P\oplus R) = Q\oplus R = Z$,实际上 XY=ZX \oplus Y = Z,所以 XYZ=ZZ=0X \oplus Y \oplus Z = Z \oplus Z = 0)。

    “不能两两不同”的条件等价于什么?

    • P=QP=Q 当且仅当 X=0X=0
    • P=RP=R 当且仅当 Y=0Y=0
    • Q=RQ=R 当且仅当 Z=0Z=0

    所以“至少两个相等”意味着 X,Y,ZX, Y, Z至少有一个为 00

    由于 XY=ZX \oplus Y = Z,如果 X=0X=0,则 Z=YZ=Y;如果 Y=0Y=0,则 Z=XZ=X;如果 Z=0Z=0,则 X=YX=Y


    动态规划状态

    dp[t]dp[t] 表示当前状态(某个值)的方案数。但直接记录 (P,Q,R)(P,Q,R) 三元组不可行(值域太大)。

    观察到每次操作只影响一个变量,且我们只关心相等关系。

    实际上,可以证明只需要关心 (PQ,PR)(P \oplus Q, P \oplus R) 这对值
    d1=PQd1 = P \oplus Qd2=PRd2 = P \oplus R,则 QR=d1d2Q \oplus R = d1 \oplus d2

    条件“至少一个为 0”意味着 d1=0d1=0d2=0d2=0d1d2=0d1 \oplus d2 = 0(即 d1=d2d1 = d2)。


    更简单的观察(标程思路)

    标程用了一个非常巧妙的方法:

    定义前缀异或:

    pre[i]=a1a2aipre[i] = a_1 \oplus a_2 \oplus \dots \oplus a_i

    注意 pre[0]=0pre[0] = 0

    然后递推关系:

    $$dp[pre[i-1]] = 3 \times dp[pre[i-1]] + 2 \times dp[pre[i]] \pmod{MOD} $$

    为什么?


    推导过程

    f(v)f(v) 表示处理完前 i1i-1 个数后,PQR=vP \oplus Q \oplus R = v 的方案数?不完全是。

    实际上,标程中的 dp[x]dp[x] 表示:当前三个变量的异或值之和为 xx 的方案数?等等,需要重新理解。

    更准确地说,标程维护的是 dp[pre[i1]]dp[pre[i-1]] 表示... 我们直接看转移:

    在处理 aia_i 之前,设:

    • p=Pp = Pq=Qq = Qr=Rr = R
    • 前缀异或 pre[i1]=a1ai1pre[i-1] = a_1 \oplus \dots \oplus a_{i-1}

    有一个关键等式:

    PQR=pre[i1]P \oplus Q \oplus R = pre[i-1]

    因为初始全 00,每次操作对一个变量异或 aja_j,三个变量整体异或值增加 aja_j,所以累加得到前缀异或。

    所以任何时候有:

    PQR=pre[i1]P \oplus Q \oplus R = pre[i-1]

    状态定义

    dp[v]dp[v] 表示处理完前 i1i-1 个数后,满足 PQ=vP \oplus Q = vRR 由上式确定的方案数

    注意:PQ=vP \oplus Q = v,且 PQR=pre[i1]P \oplus Q \oplus R = pre[i-1],所以 R=vpre[i1]R = v \oplus pre[i-1]

    同时 Q=PvQ = P \oplus vR=vpre[i1]R = v \oplus pre[i-1]PP 可以任意?不,需要保证 P,Q,RP,Q,R 不两两不同条件。


    转移分析

    对于当前 aia_i,三种操作:

    1. 操作 PPP=PaiP' = P \oplus a_iQ=QQ'=QR=RR'=R
      新 $P' \oplus Q' = (P \oplus a_i) \oplus Q = v \oplus a_i$
      pre=pre[i1]ai=pre[i]pre' = pre[i-1] \oplus a_i = pre[i]

    2. 操作 QQP=PP'=PQ=QaiQ'=Q \oplus a_iR=RR'=R
      新 $P' \oplus Q' = P \oplus (Q \oplus a_i) = v \oplus a_i$

    3. 操作 RRP=PP'=PQ=QQ'=QR=RaiR'=R \oplus a_i
      PQ=PQ=vP' \oplus Q' = P \oplus Q = v(不变)
      但注意 R=RaiR' = R \oplus a_i,而 R=vpre[i1]R = v \oplus pre[i-1],所以新 pre=pre[i]=pre[i1]aipre' = pre[i] = pre[i-1] \oplus a_i,检查一致性:
      新 $P' \oplus Q' \oplus R' = v \oplus (v \oplus pre[i-1] \oplus a_i) = pre[i-1] \oplus a_i = pre[i]$ ✅


    条件“不能两两不同”等价于什么?

    P,Q,RP,Q,R 两两不同当且仅当 PQP \neq QPRP \neq RQRQ \neq R
    PQ=vP \oplus Q = vPR=?P \oplus R = ?QR=v(PR)Q \oplus R = v \oplus (P \oplus R)? 不如直接用 vvpre[i1]pre[i-1] 表示。

    其实,条件“不是两两不同” = “至少一对相等”。

    • P=QP=Q 当且仅当 v=0v=0
    • P=RP=R 当且仅当 P=vpre[i1]P = v \oplus pre[i-1],即 PR=0P \oplus R = 0??
      更简单:由于 PQR=pre[i1]P \oplus Q \oplus R = pre[i-1],若 P=QP=Q,则 v=0v=0,且 2PR=pre[i1]2P \oplus R = pre[i-1],即 R=pre[i1]R = pre[i-1]
      但我们需要判断所有可能性。

    标程的简洁结论

    经过推导(此处省略完整代数细节),最终得到非常简单的递推:

    dp[x]dp[x] 表示当前 PQ=xP \oplus Q = x 的方案数。
    则处理 aia_i 时:

    $$dp[pre[i-1]] = 3 \cdot dp[pre[i-1]] + 2 \cdot dp[pre[i]] $$

    其中 pre[i]=pre[i1]aipre[i] = pre[i-1] \oplus a_i

    为什么?

    • 操作 RR 保持 vv 不变(v=PQv = P\oplus Q),所以 dp[v]dp[v] 贡献 11 倍(但标程中是 33 倍,说明初始 dp[pre[i1]]dp[pre[i-1]]33 来自三种操作都可能导致 vv 不变?需要仔细核对)
    • 操作 PPQQ 使 vv 变为 vaiv \oplus a_i,且要求新状态合法,等价于 vaiv \oplus a_i 的某个条件...

    实际上,最终结论是:

    $$dp[pre[i-1]]_{\text{new}} = 3 \cdot dp[pre[i-1]]_{\text{old}} + 2 \cdot dp[pre[i]]_{\text{old}} $$

    且其他 dpdp 值不变。


    初始与答案

    初始 i=0i=0pre[0]=0pre[0]=0dp[0]=1dp[0]=1(只有 P=Q=R=0P=Q=R=0PQ=0P\oplus Q=0)。

    最后,所有 PQP\oplus Q 可能值的 dpdp 值之和就是答案,因为每个 dpdp 对应一组合法的 (P,Q,R)(P,Q,R) 且满足最终条件。


    示例验证

    第一个样例:n=3, a=[1,7,9]n=3,\ a=[1,7,9]

    • pre[0]=0, dp={0:1}pre[0]=0,\ dp=\{0:1\}
    • i=1, a1=1, pre[1]=1i=1,\ a_1=1,\ pre[1]=1
      dp[0]=31+2dp[1]=3+0=3dp[0] = 3*1 + 2*dp[1]=3+0=3dpdp 变为 {0:3}\{0:3\}
    • i=2, a2=7, pre[2]=17=6i=2,\ a_2=7,\ pre[2]=1\oplus7=6
      dp[0]=33+2dp[6]=9+0=9dp[0] = 3*3 + 2*dp[6]=9+0=9
    • i=3, a3=9, pre[3]=69=15i=3,\ a_3=9,\ pre[3]=6\oplus9=15
      dp[0]=39+2dp[15]=27+0=27dp[0] = 3*9 + 2*dp[15]=27+0=27

    答案 =dp[0]=27=dp[0]=27?但示例输出是 33!说明我理解有误。

    实际上标程最后是 求所有 dpdp 值的和,而不是只取 dp[0]dp[0]
    而且 dpdp 中除了 pre[i1]pre[i-1] 位置,其他位置也会变化,但标程只更新了 dp[pre[i1]]dp[pre[i-1]],其他值保持不变?这不可能,因为 dp[pre[i]]dp[pre[i]] 也参与计算但未被更新。

    仔细看:转移中 dp[pre[i1]]dp[pre[i-1]] 用到了 dp[pre[i]]dp[pre[i]],但 dp[pre[i]]dp[pre[i]] 是上一轮的值,不会被这轮覆盖(因为当前轮只更新 pre[i1]pre[i-1] 位置)。所以 dpdp 是逐步累积的。


    经过严格推导(可参考官方题解),最终答案为:

    xdp[x]\sum_{x} dp[x]

    其中 dpdp 按上述递推。

    对于样例1,手动模拟:

    • 初始:dp[0]=1dp[0]=1
    • i=1, pre1=1: dp[0]=31+2dp[1]=3dp[0] = 3*1 + 2*dp[1]=3dp[1]dp[1] 不变(0)
    • i=2, pre2=6: dp[1]=30+2dp[6]=0dp[1] = 3*0 + 2*dp[6]=0dp[6]dp[6] 不变
    • i=3, pre3=15: dp[6]=30+2dp[15]=0dp[6] = 3*0 + 2*dp[15]=0

    最终 dp[0]=3dp[0]=3dp[1]=0dp[1]=0dp[6]=0dp[6]=0dp[15]=0dp[15]=0,和为 33,匹配输出。


    复杂度

    • 每个测试用例 O(n)O(n)
    • 使用 map 存储非零 dpdp 值,因为 prepre 值范围大但不同值数量有限
    • 总复杂度 O(nlogn)O(n \log n),满足 2×1052\times10^5

    总结

    本题的核心:

    1. 利用 PQR=pre[i1]P \oplus Q \oplus R = pre[i-1] 化简状态
    2. 仅维护 PQP \oplus Q 的分布
    3. 发现递推仅涉及 pre[i1]pre[i-1]pre[i]pre[i] 两个位置
    4. 答案即为所有 dpdp 值之和

    这是 XOR 与 DP 结合的经典题目,关键在于找到不变量并压缩状态。

    • 1

    信息

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