当前位置: 代码迷 >> 综合 >> Playing games
  详细解决方案

Playing games

热度:63   发布时间:2024-02-24 15:15:07.0

题目:
https://ac.nowcoder.com/acm/contest/295/H

有n个数,选出尽量多的数使得异或和为000
1≤n≤500000,0≤ai≤5000001\le n\le 500000,0\le a_i\le 5000001n500000,0ai?500000
思路:
问题等价于选出尽量少的数使得异或和为全部数的异或和valvalval。根据线性基思想可以推得整个集合的异或集合可以被不超过191919个数的异或集合表示.因此答案也不超过191919。所以可以二分答案。
那么如何判断选midmidmid个数能否异或成valvalval,可以用生成函数A=∑i=0500000aixiA=\sum_{i=0}^{500000}a_ix^iA=i=0500000?ai?xiai=1a_i=1ai?=1表示这个数存在,为000表示不存在,AkA^kAk就表示选kkk个,只不过这里是多项式的异或,用FWTFWTFWT,而且算B=AkB=A^kB=Ak,可以直接算FWT(B)=FWT(A)kFWT(B)=FWT(A)^kFWT(B)=FWT(A)k,这样只要把AAA变成FWT(A)FWT(A)FWT(A),然后对每一位算kkk次幂,再把FWT(B)FWT(B)FWT(B)变成BBB就行,类似点值表示法。
还要注意一点,这样会选重复,所以没法直接判断能否刚好选midmidmid个数,但是重复的异或会抵消,相当于选的个数少于mid,因为是二分判断,所以退而求其次,变成判断能否用少于midmidmid个数,那么这样生成函数a0=1a_0=1a0?=1,代表可以不选。

总结:
异或的卷积形式和加得到的卷积类似,也可以用生成函数。

  相关解决方案