题目大意:

花神的题目是这样的 设 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. MariaDB 安装与启动 过程记录

    1. 安装之前的准备工作 rpm -qa |grep mysql rpm -qa |grep mariadb 按照查出来的软件包使用  yum remove  全部卸载,当然也可以 yum remov ...

  2. PyCharm Tips 常用操作帮助

    以下内容转自 http://www.2cto.com/os/201410/341542.html --------------------------------------------------- ...

  3. 磁盘挂载问题:Fdisk最大只能创建2T分区的盘,超过2T使用parted

    需求说明:云服务器上买了一块8T的磁盘,准备挂载到服务器上的/data目录下. ===================================parted命令说明=============== ...

  4. webvirtmgr-重命名kvm虚拟机的名称

    之前部署了Webvirtmgr平台管理kvm虚拟机,由于虚拟机在创建时名称是顺便起的,后续在虚拟机上部署了部分业务.为了便于管理,最好将虚拟机的名称重置下. 现在说下如何修改kvm中虚拟机的名称: 比 ...

  5. HTTP协议基础与web服务的重定向,跳转以及请求转发

    JavaWeb中,HttpServletRequest与HttpServletResponse几乎是处理各种请求与操作必备的参数,与原始的ServletRequest/ServletResponse相 ...

  6. 快速搭建BIND服务,并实现解析

    公司有测试需求,当连接一个网络后自动会进入产品的测试环境,所以搭建了一个DNS解析服务,来完成此需求. 参考:http://blog.chinaunix.net/uid-30149335-id-506 ...

  7. 898 C. Phone Numbers

    传送门 [http://codeforces.com/contest/898/problem/C] 题意 题意比较难理解直接看样例就知道了,给你个n接下来n行,每行包括一个名字和号码的数量,还有具体的 ...

  8. 对于windows 10使用感受

    windows 10是美国微软公司研发的新一代跨平台及设备应用的操作系统.在2015年7月29日12点起,windows 10推送全面开始,windows 7.windows 8 用户可以升级到win ...

  9. squid反向代理

    反向代理的作用是就爱那个网站中的静态自原本地化.也就是将一部分本应该有原是服务器处理的请求交给 Squid 缓存服务处理 编辑 Squid  服务程序的配置文件*(正向代理与反向代理不能同时使用,) ...

  10. opencv学习笔记(四)

    ROI---设定感兴趣的区域(region of interest) 定义: Mat imageROI; //方法一:通过Rect指定矩形区域 imageROI=image(Rect(500,250, ...