【子集卷积】【51nod 1824】染色游戏

Description

原题链接
有 n 个红球, m 个蓝球,从中取出 x 个红球和 y 个蓝球排成一排的得分是 rx⋅by ,其中 r0=b0=1 。
定义 f(t) 表示恰好取出 t 个球排成一排的所有可能局面的得分之和。
两个局面相同,当且仅当这两排球的个数相等,且在对应列位置上的颜色都是相同的。
小Q想知道,有多少 t (1≤t≤n+m) 使得 f(t) 是奇数,你能告诉他满足条件的 t2 之和吗?
对于样例, f(1)=2,f(2)=5,f(3)=13,f(4)=28,f(5)=50,f(6)=60 ,答案是 2^2+3^2=13 。

Analysis

以下讨论均在 mod 2 m o d   2 意义下进行。

f(t)=i=0tribtiCit f ( t ) = ∑ i = 0 t r i b t − i C t i

=i=0tribti[it] = ∑ i = 0 t r i b t − i [ i ⊆ t ]
这一步可以由Lucas定理得出
=itribti = ∑ i ⊆ t r i b t − i
看出这就是一个子集卷积裸题,使用经典的 O(nlog2n) O ( n l o g 2 n ) 算法即可
题外话:此题卡时间卡空间,我写了循环展开。

子集卷积

要求

ct=p,qapbq[pq=t][pq=0] c t = ∑ p , q a p b q [ p ∪ q = t ] [ p ∩ q = 0 ]

ct=pq=tapbq[bitcnt(p)+bitcnt(q)=bitcnt(t)] c t = ∑ p ∪ q = t a p b q [ b i t c n t ( p ) + b i t c n t ( q ) = b i t c n t ( t ) ]
bitcnt(x) b i t c n t ( x ) 表示二进制 x x 中1的个数。如果能把后面的表达式去掉就爽了,直接上集合并卷积就没了。
能不能以枚举后面的bitcnt为代价去掉中括号呢?
f[i][s]=[bitcnt(s)=i]ts[bitcnt(t)=i]at,类似有 g[i][s] g [ i ] [ s ] , h[i][s] h [ i ] [ s ] ,这些都可以直接 O(nlog2n) O ( n l o g 2 n ) dp(FMT)搞出来
那么 h[k][s]=ki=0f[i][s]g[ki][s] h [ k ] [ s ] = ∑ i = 0 k f [ i ] [ s ] ∗ g [ k − i ] [ s ] ,这相当于在每一个 bitcnt b i t c n t 上做集合并卷积,这里的计算显然也是 O(nlog2n) O ( n l o g 2 n )
最后只需要对 h[k][s] h [ k ] [ s ] 进行子集减重(逆FMT), h[bitcnt(s)][s] h [ b i t c n t ( s ) ] [ s ] 就是答案
另一方面,注意
pq=tapbq[bitcnt(p)+bitcnt(q)=bitcnt(t)] ∑ p ∪ q = t a p b q [ b i t c n t ( p ) + b i t c n t ( q ) = b i t c n t ( t ) ]
等价于
p xor q=tapbq[bitcnt(p)+bitcnt(q)=bitcnt(t)] ∑ p   x o r   q = t a p b q [ b i t c n t ( p ) + b i t c n t ( q ) = b i t c n t ( t ) ]

所以可以用类似上面的方法,使用快速沃尔什变换(FWT)。复杂度一致,但是不如FMT好用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值