P9387 巧克力
2023-08-09 20:33:46 # OI # Problem

题面

思路

4k4k+14k+24k+3=04k\oplus{4k+1}\oplus{4k+2}\oplus{4k+3}=0

这样就可以快速处理出xx的值。

我们设fi,j,k=0/1,t=0/1f_{i,j,k=0/1,t=0/1}表示我考虑了二进制的前ii(0i)(0\sim{i}),当前位将向下进位的值是j,j0nj,j\in{0\sim{n}}kk表示bb是否大于00true/falsetrue/falsett表示前ii位是否大于nn,此时的方案数。

bb大于或等于00

那就可以从低位到高位进行 DP 了,初始时f1,0,0,0=1f_{-1,0,0,0}=1

转移方程是:

fi+1,y,Obt,0/1+=fi,j,t,kf_{i+1,y,O_b|t,0/1}+=f_{i,j,t,k}

这里y=Oa+Ob+Oc+j2y=\lfloor\frac{O_a+O_b+O_c+j}{2}\rfloor

OxO_x代表xx的当前这一位的值,由于要满足(a+b+c)ac=x(a+b+c)\oplus{a}\oplus{c}=x,因此设z=Oa+Ob+Oc(mod2)z={O_a+O_b+O_c}\pmod{2}zOaOc=Oxz\oplus{O_a}\oplus{O_c}=O_x。而这位的Oa,Ob,OcO_a,O_b,O_c分别枚举一下就好了,选出符合这个条件的进行转移。

nn个二进制数加起来最多进n1n-1位,三个数最多进22位。

至于n\le{n},假如下一位小于nn的下一位,那么就是小于
nn,为00,假如下一位和nn相同,那就继承上一个状态,因为还要接着比下去,如果下一位比nn大,那就是大于,为11

最后的答案就是f60,0,1,0f_{60,0,1,0},因为1e181e18的二进制位数不会超过6060位。