1 条题解
-
0
自动搬运
来自洛谷,原作者为

Little09
「按照我们原来的期待 去证明我们的未来」搬运于
2025-08-24 22:45:39,当前版本为作者最后更新于2023-03-08 11:04:18,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先我们把每道题
H看做 ,E看做 的话,那么条件变成了选若干道题并排序,使得相邻两项满足前一项是后一项的子集。把状态相同的题目放在一起考虑,假设有 道题,那么选择至少一题的方案数就是:
可以直接预处理。那么现在我们需要按顺序进行 DP 转移,有以下几种方法:
直接暴力
定义 表示最后一项是 的选法的方案数,那么每次的转移我们需要枚举 的所有子集进行转移,按 大小依次转移。直接转移的总复杂度为 。
分成前后两部分
这套路某年 CSP 初赛考过。
刚才的瓶颈在于枚举子集,那能不能改进一下。考虑 表示所有 的和,其中 需要满足前 位是 ,后 位是 ,其中 是 的子集。
这样我们每次计算 的时候只要枚举上一个的前 位,转移 的时候枚举后 位,复杂度大致是 ,可以精细分析到更准确的下界 ,空间可以做到 。
for (int i=0;i<=mx;i++) { if (b[i]==0) continue; int A=i>>10,B=i&1023; ll res=1; for (int j=0;j<1024;j++) if ((j&A)==j) (res+=dp[j][B])%=mod; f[i]=val[i]*res%mod; for (int j=0;j<1024;j++) if ((j&B)==B) (dp[A][j]+=f[i])%=mod; (ans+=f[i])%=mod; }按 顺序
考虑按 顺序进行 DP 转移,也就是按照 分成 层,每一层一定是从之前的层里转移过来。那么我们只需要做完每一层后做一次 FMT 累计入答案,每次计算 的时候可以直接 计算,这样时间可以做到 ,空间可以做到 。
for (int i=0;i<=m;i++) { for (int j=0;j<(1<<m);j++) dp[j]=0; for (int j=0;j<(1<<m);j++) { if (__builtin_popcount(j)!=i) continue; dp[j]=(1+s[j])*val[j]%mod; (ans+=dp[j])%=mod; } FMT(); }FMT 同时转移(官方做法)
考虑我们执行 FMT 的过程,比方说在做完前 位的时候我们得到的数组是什么: 是需要满足前 位是 的前 位的子集, 位以后恰好就是 的 位以后,这样的位置的和。
我们直接定义 表示所有 的和,其中 满足前 位是 的前 位的子集, 位以后恰好就是 的 位以后。如果我们计算出了 ,我们可以在 的时间里计算出 的每个位,递推即可。而我们如果得到了所有 满足 ,我们也可以 计算出 ,枚举不同的第一个位置转移即可。
这样可以做到时间 ,空间 。
for (int i=0;i<(1<<m);i++) { dp[i]=1; for (int j=0;j<m;j++) if (i&(1<<j)) (dp[i]+=s[j][i^(1<<j)])%=mod; dp[i]=dp[i]*val[i]%mod; s[0][i]=dp[i]; (ans+=dp[i])%=mod; for (int j=1;j<m;j++) { s[j][i]=s[j-1][i]; if (i&(1<<(j-1))) (s[j][i]+=s[j-1][i^(1<<(j-1))])%=mod; } }分治
考虑对最高位 分治,也就是在 trie 的结构上做类似 CDQ 分治的东西。那么就是先做左儿子,接下来考虑左儿子对右儿子的贡献,再做右儿子。
考虑记以 结束的答案为 ,我们还需要在 trie 上一边遍历一边维护 的 FMT 数组 ,假设当前做到的位是 ,目前已有的数是 ,我们需要 是 的和,其中 满足满足最高的 位和 相同,后面的位是 子集。那么在每个节点做完左右儿子后,我们把当前子树内的 从左儿子向右儿子累加即可。
时间复杂度为 ,空间复杂度为 。
void solve(int i,int S) { if (i==-1) { Add(g[S],dp[S]); return; } solve(i-1,S); for (int T=0;T<(1<<i);T++) Add(dp[S|T|(1<<i)],g[S|T]*val[S|T|(1<<i)]%mod); solve(i-1,S|(1<<i)); for (int T=0;T<(1<<i);T++) Add(g[S|T|(1<<i)],g[S|T]); }
- 1
信息
- ID
- 8462
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者