E.triples ll
题意
让你用$n$个3的倍数,把$a$或出来,问你有几种方案,对998244353取模
思路
在二进制中$1,4,16,\mod 3余1$, 而 $2,8,32 \mod 3余2$
首先如果$a$中为$1$的二进制位在$b$中也都为$1$,那么就称$a$是$b$的子集
我们用$dp[i][j]$来表示二进制位$mod$ $3$ 余$1$的个数为$i$,$mod$ $3$ 余$2$的个数为$j$并且所有是3的倍数的子集个数
我们可以先一个$(logn)^4$求出所有的$dp$值
1 | void Fac() { |
如果要求或出来的结果是$a$的子集,那么方案数就是$(a的子集的个数)^n$
但是题目要求或出来的结果是$a$,那我们就要容斥一下了
打个比方,现在$a$的$\mod2$的个数为$1$,$\mod1$的个数为$2$
那么$dp[2][1]$所代表的是$<2,1>$的子集的个数,但有些子集在相或$n$次以后得不到a,这时候就要减掉那些不能或到$a$的子集 2,1>
$dp[2][1]$就像上图中由 A-E,A-D,A-C,B-E,B-D,B-C 组成,而能或出来$a$的只有A-E,那么我们就要把其余不满足的减掉,也就是减掉$dp[1][1]+dp[2][0]$,发现减多了,我们要加上$dp[1][0]+dp[0][1]$,后面就跟容斥一样,多写几个样例就会发现当$(num1+num2-i-j)\mod2$时是减,其他是加。
注意:减的时候减掉的是不符合个数的$n$次幂
AC代码
1 |
|