尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

[模拟赛]拆分(div)

[模拟赛]拆分(div)
📅 发布时间:2026/6/20 1:12:17

前言:

之前考过,现在被拿来作为DIV2的T3,给学第、学妹们考。回忆的时候对状态的设计没有太清晰还是写一下吧。

题面描述:

给定一个数 \(n\),你需要输出将 \(n\) 拆分成若干可重无序的二的次幂的方案数。答案对 \(10^9+7\) 取模。

解题思路:

首先有一个结论,那就是如果 \(n\) 为 \(2^i\),那么分成大于等于两份的话,对拆分出来的的数排序后一定存在一个前缀和为 \(2^{i-1}\)。

因为小于 \(2^i\) 的最大的 \(2\) 的整数次幂只有 \(2^{i-1}\),所以如果拆出 \(2^{i-1}\) 那么一定会有一个前缀和为 \(2^{i-1}\),如果不拆,那么只能拆更小的数,肯定能组成 \(2^{i-1}\)。

所以设计状态,\(f_{i,j}\) 表示用 \(\le 2^{j}\) 的数组成 \(2^i\) 的方案数。

根据上面所说的结论,可以知道排完序后,存在一个前半部分和为 \(2^{i-1}\),后半部分和为 \(2^{i-1}\)。

考虑 \(f_{i,j}\) 的值,转移枚举 \(k \le j\) 表示前半部分所用的数 \(\le 2^{k}\) 组成 \(2^{i-1}\) 的方案数,后半部分用区间 \([2^k, 2^j]\) 的数字组成 \(2^{i-1}\) 的方案数。\(f_{i,j}\) 为两部分的乘积。

前半部分是简单的,后半部分可以将所有数字 \(\div 2{k}\) 这样后半部分就变为了使用区间 \([1,2^{j-k}]\) 的数组成和为 \(2^{i-1-k}\) 的方案数了。即:

\[f_{i,j} \longleftarrow \sum _{k=0}^{j} f_{i-1,k} \times f_{i-1-k,j-k} \]

那么现在我们会做 \(n\) 是 \(2\) 的整数次幂的情况了,考虑不是 \(2\) 的次幂的情况。

还有个结论,那就是一个数 \(n\) 拆分完后排序,一定存在一个前缀和为 \(lowbit(n)\)。

考虑扩大范围,即排序后,一定存在一种划分方案,使得每段为 \(2^{a_{i}}\),\(a_{i}\) 为 \(n\) 从低到高考虑第 \(i\) 个二进制为 \(1\) 的位置。

那么设计状态 \(g_{i,j}\) 表示用 \(\le 2^{j}\) 的数字拼出了最低的 \(i\) 个 \(2\) 进制为 \(1\) 的位置的方案数。

推的方法同理。

\[g_{i,j} \longleftarrow \sum _{k=0}^{j} g_{i-1,k} \times f_{a_{i}-k,j-k} \]

时间复杂度: \(O(\log^3 n)\)。

代码实现:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 70, mod = 1e9 + 7;
int n, m, tot, cnt, f[N][N], g[N][N], a[N];
void add(int &x, int y){x = (x + y) % mod;}
void solve(){cin >> n, cnt = tot = 0, m = log2(n);while(n){if(n & 1) a[++tot] = cnt;++cnt;n >>= 1;}for(int i = 0; i <= m + 1; i++)for(int j = 0; j <= m + 1; j++) f[i][j] = g[i][j] = 0;f[0][0] = 1;for(int i = 1; i <= m; i++){f[i][i] = 1;for(int j = 0; j <= i; j++){for(int k = 0; k <= j; k++)add(f[i][j], f[i - 1][k] * f[i - 1 - k][j - k] % mod);}}g[0][0] = 1;for(int i = 1; i <= tot; i++){for(int j = 0; j <= a[i]; j++){for(int k = 0; k <= j; k++){add(g[i][j], g[i - 1][k] * f[a[i] - k][j - k] % mod);}}}int ans = 0;for(int i = 0; i <= m; i++) add(ans, g[tot][i]);cout << ans << endl;
}
signed main(){freopen("div.in", "r", stdin);freopen("div.out", "w", stdout);int T;cin >> T;while(T--) solve();return 0;
}

相关新闻

  • 详细介绍:【微服务组件】Springboot结合Dubbo实现RPC调用
  • 怎么理解np.array([10, 20]).reshape(-1, 1)?
  • 深入解析:网络安全等级保护测评高风险判定实施指引(试行)--2020与2025版对比

最新新闻

  • 终极指南:如何使用 nunif iw3 将普通2D视频转换为沉浸式VR 3D体验
  • Display Driver Uninstaller深度清理方案:显卡驱动残留问题的终极解决方案(2024版)
  • 上海正规靠谱空调维修公司推荐,全城优选上海迪迅通制冷设备 - 星际AI
  • SPI协议深度解析:从时钟相位到错误处理,以MC68HC908GR8为例
  • 5分钟掌握2D转3D视频转换:让平面影像立体化的AI魔法
  • 嵌入式系统热设计与功耗分析:从LPC435x数据手册到可靠硬件设计

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号