bzoj3209 花神的数论题——数位dp
题目大意:
花神的题目是这样的 设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你 派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。
要对10000007(非质数)取模
n<=10^15
分析:
O(nlogn)暴力显然可以想出来。显然会tle
这是从1~n一个一个枚举并变成二进制算的,但是我们是否可以向普通的数位dp,一次性枚举许多个数呢?
二进制的n,大概最多50位。例如21=10101.它显然可以拆成二进制下的10000+100+1
那么,我们是否可以尝试着去先算出来1~10..0的sum乘积?
假设这是一个n位数,也就是有n-1个零
考虑只有一个1的数字个数,C(n,1),即,在n个位置上,取1个位置变成1的方案数。那么,sum[i]=1的数的贡献就是1^c(n,1)
只有二个1,C(n-1,2),注意,是n-1位,因为除了特殊的10..000之外,其他的数都只有n-1个位置可放1。同理,sum[i]=2的数的贡献就是2^c(n-1,2),因为本身就是连乘嘛,交换律结合律就先把不同个数的数所做的贡献乘起来。
三个1同理。
……
以21=10101为例,这样我们可以切掉n的第一个10000以下的方案。
现在我们要处理10001~10100的方案数,我们仍然可以利用刚才处理100的思路,
只是,放一个1在最后的三位,必然每次都要加上之前已经有过的那一个1(10000),所以,是2^c(3,1)
2个1同理,是3^c(2,2)
这样,就解决问题了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=;
ll ans=;
ll sum;
ll wei;
ll c[][];
ll n;
ll qm(ll x,ll y)
{
ll ret=,base=x;
while(y)
{
if(y&) ret=(ret*base)%mod;
base=(base*base)%mod;
y>>=;
}
return ret;
}
int main()
{
c[][]=;
for(int i=;i<=;i++)
{
c[i][]=;
for(int j=;j<=;j++)
c[i][j]=c[i-][j-]+c[i-][j];
}//直接打表就好,
//注意,组合数将作为指数部分,不能取模 C(50,25)long long也开的下,
scanf("%lld",&n);
wei=;sum=;//sum,已经处理出来的之前的1的个数
for(wei=;wei>=;wei--)//按位枚举
{
if(n&((ll)<<wei-))
{
ans=(ans*qm(sum+,wei))%mod;//处理1个的特殊情况
for(int k=sum+,s=;k<=sum+wei-;k++,s++)
{
ans=(ans*qm(k,c[wei-][s]))%mod;
}
sum++;
}
}
printf("%lld",ans);
return ;
}
总结:
数位dp的最初思想的来源,就是利用整千,整万,整十万的整齐特殊性质,可以利用可以想到的数学方法,对枚举进行大幅的简化,直接减少到O(logn)
这个题其实算是数位dp的裸题,还是比较常规的。
对于其他的符合规定的第k小的数(启示录),是先预处理整位的情况,再按位枚举,考虑每个数能填几,从而类似康拓展开,找到第k小的数。
或者[l,r]区间内多少个满足限制的数,前缀和思想,求l-1以内,再求r以内做差就好。
bzoj3209 花神的数论题——数位dp的更多相关文章
- BZOJ3209: 花神的数论题(数位DP)
题目: 3209: 花神的数论题 解析: 二进制的数位DP 因为\([1,n]\)中每一个数对应的二进制数是唯一的,我们枚举\(1\)的个数\(k\),计算有多少个数的二进制中有\(k\)个\(1\) ...
- [bzoj3209][花神的数论题] (数位dp+费马小定理)
Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...
- 【BZOJ3209】花神的数论题 数位DP
[BZOJ3209]花神的数论题 Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级 ...
- BZOJ 3209: 花神的数论题 [数位DP]
3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...
- BZOJ 3209 花神的数论题 数位DP+数论
题目大意:令Sum(i)为i在二进制下1的个数 求∏(1<=i<=n)Sum(i) 一道非常easy的数位DP 首先我们打表打出组合数 然后利用数位DP统计出二进制下1的个数为x的数的数量 ...
- bzoj 3209 花神的数论题 —— 数位DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3209 算是挺简单的数位DP吧,但还是花了好久才弄明白... 又参考了博客:https://b ...
- 洛谷$ P$4317 花神的数论题 数位$dp$
正解:数位$dp$ 解题报告: 传送门! 开始看到感觉有些新奇鸭,仔细一想发现还是个板子鸭,,, 考虑设$f_{i}$表示$sum[j]=i$的$j$的个数 日常考虑$dfs$呗,考虑变量要设哪些$Q ...
- 花神的数论题(数位dp)
规定sum[i] 为i里面含1的个数 ,求从1-N sum[i]的乘积. 数为64位内的,也就是sum[i]<=64的,这样可以dp求出1-N中含k个1的数有多少个,快速幂一下就可以了. 有个地 ...
- BZOJ3209 花神的数论题 【组合数学+数位DP+快速幂】*
BZOJ3209 花神的数论题 Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有 ...
随机推荐
- QQ群管理员申请帖(本次截止日期为2017-03-25)
本帖专门为技术交流群申请管理员专用. 管理员的权利: 1.有权在成员违规的情况下直接剔除. 2.有权加入多个交流群. 3.有权引人入群. 4.艾特全体是权利,但要慎用,通常情况下,没有我本人的授意,不 ...
- 系统、决策、控制研究系列(SSDC)
本类目主要介绍的书籍来自springer的系列书籍中的一本,对于该系列书籍介绍如下: “系统.决策及控制研究”(SSDC)系列涵盖了在广泛认知的系统.决策及控制的各个领域的快速.最新和高质量的最新发展 ...
- 《Linux内核分析》第四周学习总结
<Linux内核分析>第四周学习总结 ——扒开系统调用的三层皮 姓名:王玮怡 学号:20135116 理论总结部分: 第一节 用户态.内核 ...
- 小学生四则运算App实验成果
组名:会飞的小鸟 组员:徐侃 陈志棚 罗伟业 刘芮熔 成员分工: ①刘芮熔:设置安卓包.界面的代码,界面的排序. ②陈志棚:加减乘除的判断异常处理,例如除数不能为零的异常处理等问题. ③徐侃 ...
- 第三个sprint冲刺第一阶段
- weex 开发踩坑日记--环境配置、安卓运行、adb、开发
环境配置方面 1.需要安装java和android环境,java的话一定要下载jdk而不是jre. 在"系统变量"新建一个变量名为JAVA_HOME的变量,变量值为你本地java的 ...
- window.setTimeout
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout
- Java基础实践一:for关键字的实现原理
Java源码: /** * Demo.java * com.yuanchuangyun.libra.web * * * ver date author * ────────────────────── ...
- Linux CentOS虚拟机网卡配置
最近在VMware安装CentOS6.5之后,每次从宿主机访问虚拟机的Oracle时,都要修改IP地址,因为没有设置虚拟机的IP,所以每次开机之后虚拟机的IP地址都是随机的,于是研究了下给虚拟机配置静 ...
- [转帖] Win10 多桌面转换的快捷键
http://down.52pk.com/zhishi/52202.shtml win10系统中用户除了可以切换任务之外,还可以进行多桌面切换,就像是切换了电脑屏幕一样,可能网友们还都不知道win10 ...