博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【花神的数论题】
阅读量:5343 次
发布时间:2019-06-15

本文共 1226 字,大约阅读时间需要 4 分钟。

定义\(sum(i)\)表示\(i\)在二进制下\(1\)的个数

\(\prod_{i=1}^{n}sum(i)\)

暴力非常\(sb\)显然可以随便写,但是显然也是会\(T\)

于是我们换个思路

我们设\(tot\)表示\(sum(i)=x\)\(i\)有多少个,于是答案就是\(x^{tot}\)

我们枚举\(x\)就行了,\(x\)显然不会很大,也就是\(log_2{n}\)

之后就可以开始数位\(dp\)

我们设\(dp[i][0/1][j]\)表示最高位填到第\(i\)位,其中最高位填\(0/1\),一共填了\(j\)个1一共有多少个数

方程很显然,就是往最高位上填\(0/1\)

填0的话

\[dp[i+1][0][j]+=dp[i][1][j]+dp[i][0][j]\]

填1的话

\[dp[i+1][1][j+1]+=dp[i][0][j]+dp[i][1][j]\]

之后我们按照数位\(dp\)的套路来做就行了

代码

#include
#include
#include
#define LL long long #define re register#define maxn 55const LL mod=10000007;const LL P=9988440;LL n;int a[maxn];LL dp[maxn][2][maxn];inline LL quick(LL a,LL b){ LL S=1; while(b) { if(b&1) S=S*a%mod; b>>=1ll; a=a*a%mod; } return S;}inline LL sum(LL x){ LL cnt=0; while(x) { if(x&1ll) cnt++; x>>=1ll; } return cnt;}inline LL slove(LL x){ int num=0; while(x) { ++num; if(x&1ll) a[num]=1; x>>=1ll; }//分解数位 dp[1][1][1]=1; dp[1][0][0]=1; for(re int i=1;i
=1;i--)//之后我们卡前面的[i+1,num]为完全相等,让第i位小于n的第i位,我们就可以让后面的位数随便填了 { for(re int j=0;j

转载于:https://www.cnblogs.com/asuldb/p/10206207.html

你可能感兴趣的文章
【算法】—— 随机音乐的播放算法
查看>>
mysql asyn 示例
查看>>
DataGrid 点击 获取 行 ID
查看>>
git 使用
查看>>
边框圆角方法
查看>>
asp.net WebApi自定义权限验证消息返回
查看>>
php中eval函数的危害与正确禁用方法
查看>>
20172315 2017-2018-2 《程序设计与数据结构》第十一周学习总结
查看>>
MySQL添加、修改、撤销用户数据库操作权限的一些记录
查看>>
ViewBag & ViewData
查看>>
关于谷歌浏览器Chrome正在处理请求的问题解决
查看>>
Git核心技术:在Ubuntu下部署Gitolite服务端
查看>>
平面波展开法总结
查看>>
建造者模式
查看>>
ArraySort--冒泡排序、选择排序、插入排序工具类demo
查看>>
composer 安装laravel
查看>>
8-EasyNetQ之Send & Receive
查看>>
Android反编译教程
查看>>
java重写LinkedList
查看>>
zTree节点重叠或者遮挡
查看>>