P4317 花神的数论题,关于luogu题解粉兔做法的理解
题意
设 \(\text{sum}(i)\) 表示 \(i\) 的二进制表示中 \(1\) 的个数。给出一个正整数 \(N\) ,求 \(\prod_{i=1}^{N}\text{sum}(i)\) 。
思路
换一种角度看这个乘积,会发现就相当于统计出 \(1\sim N\) 中 1 的个数为 \(k\) 的数量 \(cnt_k\) ,然后 \(\prod k^{cnt_k}\) 即可。
(怎么那么水啊,这都什么垃圾紫题,题白挑了)为了让这道题更有价值,代码实现非常的神仙。Orz粉兔。
粉兔的代码看了很久才理解……luogu上至今没有看到公开的详解。
这里注释的是我认为正确的理解,若有差错还请指正。
代码
#include <cstdio>
#define ll long long
const ll mod=1e7+7;
ll n,ans=1,cnt,f[50];
ll power( ll a,ll b )
{
ll res=1;
for ( ; b; b>>=1,a=a*a%mod )
if ( b&1 ) res=res*a%mod;
return res;
}
int main()
{
scanf( "%lld",&n );
cnt=0; f[0]=0;
for ( int len=49; ~len; --len )
{
for ( int i=49; i; --i )
f[i]+=f[i-1];
if ( n>>len&1 ) f[cnt]++,cnt++;
//cnt记录的是除了现在这一位,之前有的1的个数,f[cnt]++表示,这一位的1产生了一种使得前面的1全部能取到的方案。
}
f[cnt]++; //加上本身
//之前一直想不明白,如果这样枚举,为什么能直接从49开始。
//一开始的想法是预支最高位的1,这样当前每次加一位就能取1,对应 f[i-1] 到 f[i] 的转移
//但是这样有个问题,就是最高位没有1了怎么办,这样预支无效,答案就会偏大
//后来发现,关键在外层循环。当位数大于二进制下n的位数的时候,f始终为0,最后一句if 不会执行,也就不会出现上述问题。
//一旦开始累加出现了值,那么一定就是有高位可以预支了。否则 if 中的等号不会成立。
for ( int i=1; i<=49; ++i )
ans=ans*power( i,f[i] )%mod;
printf( "%lld",ans );
return 0;
}
P4317 花神的数论题,关于luogu题解粉兔做法的理解的更多相关文章
- 洛谷 P4317 花神的数论题(组合数)
题面 luogu 题解 组合数 枚举有多少个\(1\),求出有多少种数 扫描\(n\)的每一位\(1\), 强制选\(0\)然后组合数算一下有多少种方案 Code #include<bits/s ...
- Luogu P4317 花神的数论题
也是一道不错的数位DP,考虑先转成二进制后再做 转化一下问题,考虑统计出\([1,n]\)中在二进制下有\(i\)个\(1\)的方案数\(cnt_i\),那么答案显然就是\(\prod i^{cnt_ ...
- 洛谷 P4317 花神的数论题 || bzoj3209
https://www.lydsy.com/JudgeOnline/problem.php?id=3209 https://www.luogu.org/problemnew/show/P4317 设c ...
- P4317 花神的数论题 dp
这题我一开始就想到数位dp了,其实好像也不是很难,但是自己写不出来...常规套路,f[i][j][k][t],从后往前填数,i位,j代表是否卡着上沿,k是现在有几个1,t是想要有几个.记忆化搜索就ok ...
- DP,数论————洛谷P4317 花神的数论题(求1~n二进制中1的个数和)
玄学代码(是洛谷题解里的一位dalao小粉兔写的) //数位DP(二进制)计算出f[i]为恰好有i个的方案数. //答案为∏(i^f[i]),快速幂解决. #include<bits/stdc+ ...
- P4317 花神的数论题 动态规划?数位DP
思路:数位$DP$ 提交:5次(其实之前A过,但是调了调当初的程序.本次是2次AC的) 题解: 我们分别求出$sum(x)=i$,对于一个$i$,有几个$x$,然后我们就可以快速幂解决. 至于求个数用 ...
- P4317 花神的数论题
题目 洛谷 数学方法学不会%>_<% 做法 爆搜二进制下存在\(i\)位\(1\)的情况,然后快速幂乘起来 My complete code #include<bits/stdc++ ...
- 洛谷P4317 花神的数论题
洛谷题目链接 数位$dp$ 我们对$n$进行二进制拆分,于是就阔以像十进制一样数位$dp$了,基本就是套模板.. 接下来是美滋滋的代码时间~~~ #include<iostream> #i ...
- 【洛谷】4317:花神的数论题【数位DP】
P4317 花神的数论题 题目背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 题目描述 话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我 ...
随机推荐
- 性能工具-mem
1.目前valgrind . memleak .free .top .ps 中vsz Rss . buddy. slab 这些用的比较多,一般用于处理内存紧张问题
- binary hacks读数笔记(nm命令)
nm命令(names):输出包含三个部分:1 符号值.默认显示十六进制,也可以指定: 2 符号类型.小写表示是本地符号,大写表示全局符号(external); 3 符号名称. 例如:nm Simple ...
- css子选择器 :frist-child :nth-child(n) :nth-of-type(n) ::select选择器
记录一下前一段时间使用.学习的几种选择器. 1. :frist-child 选择器n 比如<ul><li></li> <li></li> & ...
- SSL加密原理
对称加密算法 对称加密算法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密. 非对称加密算法 非对称加密算法(RSA)是内容加密的一类算法,它有两个秘钥:公钥与私钥 ...
- 如何用ABBYY FineReader 识别表格
ABBYY FineReader有着强大的OCR文字识别功能,不但可以将文件转换为文本文档或Word文档,也可以识别PDF文件或者图片上的表格,并且转换为Excel文件. 下面小编就使用ABBYY F ...
- 这些Stream流的常用方法你得记住,步骤简单不麻烦!
forEach遍历 /* forEach:该方法接收一个Consumer接口函数,将每一个流元素交给该函数处理 简单记: forEach方法:用来遍历流中的数据 是一个终结方法,遍历之后就不能继续调用 ...
- Java里的数组降序
Java升序容易,降序不易. 基本类型不能降序,至少要是包装类. 升序使用Arrays.sort() 降序要么使用Collections.reverse,要么实现Comparator接口 import ...
- 深入浅出之mysql索引--上
当着小萌新之际,最近工作中遇到了mysql优化的相关问题,然后既然提到了优化,很多像我这样的小萌新不容置喙,肯定张口就是 建立索引 之类的. 那么说到底,索引到底是什么,它是怎么工作的?接下来就让我和 ...
- mysql建表和建数据库语句
一.数据库操作语言 数据库在操作时,需要使用专门的数据库操作规则和语法,这个语法就是 SQL(Structured Query Language) 结构化查询语言. SQL 的主要功能是和数据库建立连 ...
- LeetCode 010 Regular Expression Matching
题目描述:Regular Expression Matching Implement regular expression matching with support for '.' and '*' ...