博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3209: 花神的数论题 (数位dp)
阅读量:6345 次
发布时间:2019-06-22

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

题目描述

背景 

众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。 
描述 
话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。 
花神的题目是这样的 
设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你 
派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。

输入

一个正整数 N。

输出

一个数,答案模 10000007 的值。

样例输入

样例输入 

3

样例输出

样例输出 

2

对于 100% 的数据,N≤10^15

题解

  数位dp,抄的大佬的题解

  然而实在不是很看得懂……

  下面$g[i]$表示$1$恰好有$i$个时候的方案数

  然后为啥能这样转移呢?我想了想,大概是因为它每一次遇到$1$时,就默认这一位可以放,那么每一个$g[i]$都能转移到$g[i+1]$,然后后面还有$1$那么考虑后面的,这样防止超出界限

1 //minamoto 2 #include
3 #define ll long long 4 const int mod=1e7+7; 5 ll ans=1,n,c,g[55]; 6 ll qpow(ll x,ll y){ 7 ll res=1; 8 while(y){ 9 if(y&1) res=res*x%mod;10 y>>=1,x=x*x%mod;11 }12 return res;13 }14 int main(){15 scanf("%lld",&n);16 for(int j=49;~j;--j){17 for(int i=49;i;--i) g[i]+=g[i-1];18 if(n>>j&1) ++g[c++];19 }20 ++g[c];21 for(int i=1;i<=49;++i) ans=ans*qpow(i,g[i])%mod;22 printf("%lld\n",ans);23 return 0;24 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9539237.html

你可能感兴趣的文章
函数为左边表达式
查看>>
读书杂谈一
查看>>
winform listbox 元素显示tooltrip
查看>>
cacti安装与配置
查看>>
TF-IDF与余弦相似性的应用(一):自动提取关键词
查看>>
javascript面向对象2
查看>>
限制容器对CPU的使用 - 每天5分钟玩转 Docker 容器技术(28)
查看>>
jquery 实现的一个 随机云标签网页背景
查看>>
RPC
查看>>
android广播事件处理broadcast receive
查看>>
在eclipse 里面 修改tomcat的配置--Server Locations
查看>>
网站 mvc url 路径 设置 为 *.html 的原因
查看>>
mybatis 开启使用 默认的 二级缓存
查看>>
docker 容器 创建和 使用
查看>>
SQLITE使用指南
查看>>
用Maven部署war包到远程Tomcat服务器
查看>>
android字体大小的设置
查看>>
2015.06.04 工作任务与心得
查看>>
icinga2使用587端口发邮件
查看>>
hpasmcli查看HP服务器内存状态
查看>>