题目大意:

花神的题目是这样的 设 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的更多相关文章

  1. BZOJ3209: 花神的数论题(数位DP)

    题目: 3209: 花神的数论题 解析: 二进制的数位DP 因为\([1,n]\)中每一个数对应的二进制数是唯一的,我们枚举\(1\)的个数\(k\),计算有多少个数的二进制中有\(k\)个\(1\) ...

  2. [bzoj3209][花神的数论题] (数位dp+费马小定理)

    Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...

  3. 【BZOJ3209】花神的数论题 数位DP

    [BZOJ3209]花神的数论题 Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级 ...

  4. BZOJ 3209: 花神的数论题 [数位DP]

    3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...

  5. BZOJ 3209 花神的数论题 数位DP+数论

    题目大意:令Sum(i)为i在二进制下1的个数 求∏(1<=i<=n)Sum(i) 一道非常easy的数位DP 首先我们打表打出组合数 然后利用数位DP统计出二进制下1的个数为x的数的数量 ...

  6. bzoj 3209 花神的数论题 —— 数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3209 算是挺简单的数位DP吧,但还是花了好久才弄明白... 又参考了博客:https://b ...

  7. 洛谷$ P$4317 花神的数论题 数位$dp$

    正解:数位$dp$ 解题报告: 传送门! 开始看到感觉有些新奇鸭,仔细一想发现还是个板子鸭,,, 考虑设$f_{i}$表示$sum[j]=i$的$j$的个数 日常考虑$dfs$呗,考虑变量要设哪些$Q ...

  8. 花神的数论题(数位dp)

    规定sum[i] 为i里面含1的个数 ,求从1-N sum[i]的乘积. 数为64位内的,也就是sum[i]<=64的,这样可以dp求出1-N中含k个1的数有多少个,快速幂一下就可以了. 有个地 ...

  9. BZOJ3209 花神的数论题 【组合数学+数位DP+快速幂】*

    BZOJ3209 花神的数论题 Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有 ...

随机推荐

  1. linux书籍

    <鸟哥私房菜-基础版> <实战LINUX_SHELL编程与服务器管理> <LINUX命令行与SHELL脚本编程大全第2版].布卢姆.扫描版> <Linux初学 ...

  2. 领跑衫获奖感言 & 课程总结

    很荣幸在最后一次课获得了黄色领跑衫.在此,我要感谢教师杨贵福,感谢<构建之法>的作者邹欣老师和出版人周筠老师,感谢“耐撕”团队的队员们. 作为旁听生,最后一堂课,有些不舍.不多说,先上图, ...

  3. 必应词典案例分析——个人博客作业week3

    案例分析 ——必应词典客户端 软件缺陷常常又被叫做Bug,即为计算机软件或程序中存在的某种破坏正常运行能力的问题.错误,或者隐藏的功能缺陷. 缺陷的存在会导致软件产品在某种程度上不能满足用户的需要.I ...

  4. Linux内核分析作业六

    1.阅读理解task_struct数据结构 2.分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构: fork进程的代码 #inclu ...

  5. 基于SSH 供应链管理系统质量属性说明

    产品的易用程度如何,执行速度如何,可靠性如何,当发生异常情况时,系统如何处理.这些被称为软件质量属性,而特性是指系统非功能(也叫非行为)部分的需求. 性能:性能就是一个东西有多快,通常指响应时间或延迟 ...

  6. "一个程序员的生命周期"读后感

    这篇文章中作者叙述了自己和大多数大学生或许都会面对的问题,即是会走过挺多的歪路,面临很多的困难和压力,但是作者却从未放弃自己真正追求的东西.对于一个过来人的经验之谈,我们应该吸取经验,在大学好好去奋斗 ...

  7. ECharts设置y轴显示

    参考地址:https://www.w3cschool.cn/echarts_tutorial/echarts_tutorial-no3h2cul.html yAxis: { type: 'value' ...

  8. Java的常用命令javac与java

    javac 可以使用javac -h来查看常用的命令: -> ~ # javac -help 用法: javac <options> <source files> 其中, ...

  9. nginx gzip 以及 tcp 反向代理的 model

    同事为了提高性能发给我一model 简单改了一下. 记录一下 #user nobody; worker_processes ; events { worker_connections ; } http ...

  10. PSexec以及xcopy的简单使用

    1. 远程执行命令. 有时候不想远程但是想执行一些命令, 比较简单的方法是: 下载systeminternals 然后解压缩后可以讲目录放到path环境变量中 然后打开命令行工具 输入 如下的命令 p ...