【BZOJ】3209: 花神的数论题
2017-02-16 09:14
316 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3209
显然是按照二进制位进行DP。
考虑预处理$F[i][j]$表示到了二进制的第$i$位,有$j$个$1$的数字有多少个。
显然:${F[i][j]=F[i-1][j-1]+F[i-1][j]}$
组合数。。。
接下来只需补充不漏的计算比$n+1$小的每一个数字对应的1的多少。数位统计即可。
View Code
(这上面表示的是有二进制中有$x$个$1$的数有多少个)
显然是按照二进制位进行DP。
考虑预处理$F[i][j]$表示到了二进制的第$i$位,有$j$个$1$的数字有多少个。
显然:${F[i][j]=F[i-1][j-1]+F[i-1][j]}$
组合数。。。
接下来只需补充不漏的计算比$n+1$小的每一个数字对应的1的多少。数位统计即可。
llg work(llg x) { llg tot=0; for (llg i=tail;i>=1;i--) { if (x<0) break; if (a[i]) { tot+=c[i-1][x]; x--; } } return tot; }
View Code
(这上面表示的是有二进制中有$x$个$1$的数有多少个)
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cstdlib> #include<cmath> #include<cstring> using namespace std; #define maxn 10010 #define md 10000007 #define llg long long #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); llg n,m,a[maxn],c[100][100],tail,ans; llg ksm(llg A,llg B) { llg ans=1; while (B) { if (B%2) ans*=A,ans%=md; A*=A; A%=md; B/=2; } return ans; } llg work(llg x) { llg tot=0; for (llg i=tail;i>=1;i--) { if (x<0) break; if (a[i]) { tot+=c[i-1][x]; x--; } } return tot; } int main() { yyj("bzoj3209"); cin>>n; n++; for (llg i=0;i<=60;i++) c[i][0]=1; for (llg i=1;i<=60;i++) for (llg j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1]; while (n!=0) { a[++tail]=n%2; n/=2; } ans=1; for (llg i=1;i<=60;i++) ans*=ksm(i,work(i)),ans%=md; cout<<ans; return 0; }
相关文章推荐
- BZOJ 3209: 花神的数论题 (数位dp)
- BZOJ 3209 花神的数论题 数位DP
- [BZOJ3209]花神的数论题(数位dp)
- [bzoj3209]花神的数论题
- BZOJ 3209: 花神的数论题 [数位DP]
- [BZOJ 3209] 花神的数论题 【数位统计】
- 【bzoj3209】 花神的数论题
- BZOJ3209 花神的数论题
- bzoj 3209: 花神的数论题 && 喵哈哈村的秘境探险(四)
- [Bzoj3209]花神的数论题(数位dp)
- bzoj 3209: 花神的数论题 (数位DP)
- BZOJ 3209 花神的数论题 数位dp
- 【bzoj3209】【花神的数论题】【数位dp+快速幂】
- BZOJ 3209: 花神的数论题【数位dp】
- 【BZOJ3209】花神的数论题 数位DP(我姿势不标准,但是可能更好写)
- [数位dp] bzoj 3209 花神的数论题
- [BZOJ3209]花神的数论题(数位dp)
- BZOJ3209:花神的数论题(数位dp)
- BZOJ 3209 花神的数论题
- bzoj3209 花神的数论题 数位DP