题目

任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量。
V1:n≤106n≤106n≤10^6。要对答案模1e9+71e9+71e9+7。
V2:n≤1030n≤1030n≤10^{30}。将整个答案输出。

解题思路

考虑每一种划分方法的序列是怎样从一个空的序列变来的。
显然,它是要么+1+1+1,要么集体乘222。
因此很快乐地得出F[x]=F[x−1]+F[x/2]∗[x%2==0]F[x]=F[x−1]+F[x/2]∗[x%2==0]F[x]=F[x-1]+F[x/2]*[x\%2==0]
当然,如果要与V2V2V2接轨,那么要换一种思路。
考虑将nnn转换为二进制,则n=Σ 2xn=Σ 2xn=\Sigma\ 2^x。
因此,如果知道每个2i2i2^i划分为2的幂的和的方案数,那么这题就很好做了。
对于某个2i2i2^i的一种划分方案,如果不是只有它本身一个数,一定可以把这些2的幂按照升序排序,然后分成两段,每一段的和都是2i−12i−12^{i−1}。
设g[i][j]g[i][j]g[i][j]表示做完了222进制下的前iii位,最大的数为2j2j2^j的方案数。
设f[i][j]f[i][j]f[i][j]表示组成2i2i2^i,最大的数为2j2j2^j的方案数。
有人想到这样的转移方程:
g[i][j]=Σjk=0 g[i−1][k]∗f[i][j]g[i][j]=Σk=0jg[i−1][k]∗f[i][j]g[i][j]=\Sigma_{k=0}^j\ g[i-1][k]*f[i][j]
f[i][j]=Σjk=0 f[i−1][k]∗f[i−1][j]f[i][j]=Σk=0jf[i−1][k]∗f[i−1][j]f[i][j]=\Sigma_{k=0}^j\ f[i-1][k]*f[i-1][j]
但是这样会算重。
为了避免这,所以强制让后面的数字大于等于2k2k2^k。
所以将后面的数字都除以2k2k2^k之后,可以得出这么一个方程:
g[i][j]=Σjk=0 g[i−1][k]∗f[i−k][j−k]g[i][j]=Σk=0jg[i−1][k]∗f[i−k][j−k]g[i][j]=\Sigma_{k=0}^j\ g[i-1][k]*f[i-k][j-k]
f[i][j]=Σjk=0 f[i−1][k]∗f[i−1−k][j−k]f[i][j]=Σk=0jf[i−1][k]∗f[i−1−k][j−k]f[i][j]=\Sigma_{k=0}^j\ f[i-1][k]*f[i-1-k][j-k]
显然先预处理fff。
然后套上高精度,再卡常,就可以通过此题了。
卡常很重要,就是拿个long doublelong doublelong\ double,确定一下log2(n)log2(n)log_2(n)
然而不知道为什么,高精度压8位WA了,压9位就没事?!

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100
#define M 150
#define mo 1000000000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{int w,a[M];
};note f[N][N],g[N][N],ans,n,c;
int i,j,k,l,ys,x,tot;
int xx;
char s[32];
double x1,x2,x3;
note operator + (const note &a,const note &b){c.w=a.w>b.w?a.w:b.w;memset(c.a,0,sizeof(c.a));int i;fo(i,1,c.w){c.a[i]+=a.a[i]+b.a[i];c.a[i+1]+=c.a[i]/mo;c.a[i]%=mo; }if(c.a[c.w+1])c.w++;return c;
}
note operator * (const note &a,const note &b){memset(c.a,0,sizeof(c.a));int i,j;long long kk;fo(i,1,a.w)fo(j,1,b.w){kk=c.a[i+j-1]+1ll*a.a[i]*b.a[j];c.a[i+j]=c.a[i+j]+kk/mo;c.a[i+j-1]=kk%mo;}c.w=a.w+b.w;while(!c.a[c.w]&&c.w>1)c.w--;return c;
}
int main(){scanf("%s",s+1);l=strlen(s+1);fo(i,1,l){x1=x1*10+s[i]-'0';}x2=log(x1)/log(2);n.w=l/9+1;fo(i,1,l){int j=(l-i)/9;n.a[j+1]=n.a[j+1]*10+(s[i]-'0');}while(!n.a[n.w]&&n.w>1)n.w--;f[0][0].w=f[0][0].a[1]=1;fo(i,1,x2){fo(j,0,i-1)fo(k,0,j)f[i][j]=f[i][j]+f[i-1][k]*f[i-1-k][j-k];f[i][i].w=f[i][i].a[1]=1;}fo(i,0,x2){if(n.a[1]&1){tot++;if(tot==1){fo(j,0,i)g[tot][j]=f[i][j];}else{fo(j,0,i)fo(k,0,j)g[tot][j]=g[tot][j]+g[tot-1][k]*f[i-k][j-k];}}ys=0;fd(j,n.w,1){x=n.a[j];n.a[j]=(n.a[j]+ys*mo)/2;ys=(ys*mo+x)&1;}while(!n.a[n.w]&&n.w>1)n.w--;}fo(i,0,99)ans=ans+g[tot][i];printf("%d",ans.a[ans.w]);fd(i,ans.w-1,1){xx=log(ans.a[i])/log(10)+1;fo(j,1,9-xx)putchar('0');printf("%d",ans.a[i]);}return 0;
}

51Nod 13831048 整数分解为2的幂相关推荐

  1. 51nod 13831048 整数分解为2的幂 [递推]【数学】

    题目连接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1048 ---------------------------- ...

  2. 51Nod-1383 整数分解为2的幂【数列】

    1383 整数分解为2的幂  任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量!由于方案数量较大,输出Mod 1000000007的结果. 比如N = 7时,共有6种划分方法. 7=1 ...

  3. 51Nod 1048 1383 整数分解为2的幂

    任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量! 比如N = 7时,共有6种划分方法. 7=1+1+1+1+1+1+1 =1+1+1+1+1+2 =1+1+1+2+2 =1+2+2+ ...

  4. 【51NOD 1048】【51NOD 1383】整数分解为2的幂 V2

    Description 任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量! 比如N = 7时,共有6种划分方法. 7=1+1+1+1+1+1+1 =1+1+1+1+1+2 =1+1+1 ...

  5. [51nod13831048]整数分解为2的幂

    题目大意 任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量! 比如N = 7时,共有6种划分方法. 7=1+1+1+1+1+1+1 =1+1+1+1+1+2 =1+1+1+2+2 =1 ...

  6. [递推] 51Nod1383 整数分解为2的幂

    简单的递推,类似背包那种加 11 或翻倍的思路. 写这题其实只是水一篇 blogblog ,其实注意还是要做 51nod1048 加强版-- #include<cstdio> #inclu ...

  7. 数论 —— 整数分解

    [概述] 整数分解目前仍是世界级难题,是非常重要的研究方向,其有很多种算法,性能上各有差异,本文仅介绍试除法.Fermat 算法.Pollard Rho 算法. [试除法] 试除法也叫穷举法,是整数分 ...

  8. VJ 1033 整数分解(版本2)

    描述 整数分解(版本2) 一个正整数可以分解成若干个自然数之和.请你编一个程序,对于给出的一个正整数n(1<=n<=1500),求出满足要求的分解方案,并使这些自然数的乘积m达到最大. 例 ...

  9. JavaScript实现判断整数是否为2的幂isPowerOfTwo算法(附完整源码)

    JavaScript实现判断整数是否为2的幂isPowerOfTwo算法(附完整源码) isPowerOfTwo.js完整源代码 isPowerOfTwo.js完整源代码 /*** @param {n ...

最新文章

  1. Spring 系列,第 2 部分: 当 Hibernate 遇上 Spring
  2. 泰勒公式推导过程_论泰勒级数在机器学习家庭中的地位
  3. getminimum_Java Calendar getMinimum()方法与示例
  4. u盾 签名pdf显示 “签名于修订版中删除”_Adobe Acrobat Reader DC for mac(免费pdf阅读)...
  5. 利用神经网络内部表征可视化class-specific image regions区域
  6. Kubernetes迁移指北 | 凌云时刻
  7. 各个ip地址库对比与java实现
  8. StartHS(截图软件)v6.81.02绿色汉化版
  9. smartadmin mysql_Smart Admin
  10. “Master”围棋对战50胜1和,人工智能身份欲揭?
  11. activities工作流入门笔记-001-建表
  12. 面试分享:专科半年经验面试阿里前端P6+总结
  13. 优化网站如何看待纯文本外链的作用
  14. PostgreSQL 元命令介绍
  15. 8. spark学习之旅(二)
  16. 图像语义分割——利用DeeplabV3+预测单张照片
  17. React hooks useState如何拿到更新后的值
  18. 语义网笔记(二) RDF
  19. Python数据分析第十二课:单变量、双变量及多变量分析图
  20. 将 Modbus 工业传感器与开源 IIoT 网关连接起来

热门文章

  1. oneinstack申请免费的R3 域名证书
  2. PHP日期时间函数之strtotime()
  3. HDLBits练习(三)多路复用器,算术电路,卡诺图电路
  4. 安装官方 Synaptics 驱动,终于解决 HP Pavilion G4 笔记本 讨厌的触摸板锁定问题!
  5. python自动生成采集规则_快速制作规则及获取规则提取器API
  6. Android6.0权限
  7. 【算力网络】算力网络的发展愿景及目标
  8. Zabbix以trapper方式监控MySQL备份文件
  9. 3 个简单的技巧让你的 vue.js 代码更优雅!
  10. 使用LDO进行电压转换,24V转5V电路为什么中间要加一个中间电压做转化