NOI online R3 T3 优秀子序列
题意:
给你一个长度为 的序列,让你找出序列所有满足条件的子集(包括空集)的价值和,一个子集满足条件当其中的任意两个元素按位与等于 ,即 ,只有一个元素的集合或空集都满足条件。
一个满足条件的集合的价值为:集合中所有元素的和 。答案对1e9+7取模。
由于是考试题,列出数据范围:
- 对于 的数据,保证 。
- 对于 的数据,保证 。
- 对于 的数据,保证 。
- 另有 的数据,保证 。
- 对于 的数据,保证 ,。
我们注意到,一个满足条件的子集没有任意两个数异或值大于零,这说明二进制的每一位,集合中最多有一个数在该位置上有值。如果集合中包含了这个数,就相当于占用了这几位,就是将状压后的每一位看成花费做背包。
具体的,可以设 表示状态为,选择前 个数和为 的方案数,因为元素和的二进制每一位最多是 ,和也不会超过最大位。最后价值和就可以枚举集合元素的和,然后预处理出来 值乘上方案数。背包第一维滚掉。
然后发现一个十分令人头大的事,对于前面 的部分分, 的值一直是 ,乘上 就已经爆的很惨了。然后仔细想想,如果是相同值的元素,在集合中肯定只会出现一次(除非是 ),因为出现两次的话按位与就不是零了,所以我们把相同值的元素压缩到一起来考虑,每次计算价值时加上它的数量。
转移背包时,枚举每个值,然后枚举所有二进制位包含它的集合, 的复杂度由于常数小可以获得 分的成绩。
当你在考虑 怎么敲暴力时,你发现用不着,前面的情况判一下如果某个值出现次数为 就可以直接 ,枚举二进制集合最多只会枚举 次,直接顺带解决了。
,只需要在枚举集合的时候将枚举完再判断改为枚举子集就可以,枚举 子集的代码:
复杂度证明,一个数二进制上如果有 个 ,那么它子集数量为 , 位的数一共有 个这样的数,那么所有 位有值的数价值和为 。
然后发现这东西等于 。所以复杂度是 。常数小点可以过去,像我的大常数代码得加点if才能过。
然后好像用多项式科技可以达到 ,这就涉及到我的知识盲区了。。。
坑的话,注意特判0,因为0可以选多个,最后要将答案乘上 ,为0的出现次数。
考场上没做出来,好菜啊。
__EOF__

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具