[BZOJ3209]花神的数论题 组合数+快速幂

Posted wls001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ3209]花神的数论题 组合数+快速幂相关的知识,希望对你有一定的参考价值。

3209: 花神的数论题

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2498  Solved: 1129
[Submit][Status][Discuss]

Description

背景
众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
描述
话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
花神的题目是这样的
设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。

 

Input

一个正整数 N。

 

Output

一个数,答案模 10000007 的值。

 

Sample Input

样例输入一

3

Sample Output

样例输出一

2

HINT

 



对于样例一,1*1*2=2;


数据范围与约定


对于 100% 的数据,N≤10^15

 

Source

原创 Memphis

 

枚举1的个数,组合数+快速幂即可。

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<algorithm>
 7 #define mod 10000007
 8 #define LL long long
 9 using namespace std;
10 LL c[65][65];
11 void pre() {
12     for(int i=0;i<=60;i++) c[i][0]=1;
13     for(int i=1;i<=60;i++) for(int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
14 }
15 LL w[100];
16 LL n,len;
17 LL power(LL a,LL b) {
18     LL ans=1;
19     while(b) {
20         if(b&1) ans*=a,ans%=mod;
21         a*=a;a%=mod;
22         b>>=1;
23     }
24     return ans;
25 }
26 LL cnt(LL x) {
27     LL ans=0;
28     for(int i=len;i>=1;i--) {
29         if(w[i]) ans+=c[i-1][x],x--;
30         if(x<0) break;
31     }
32     return ans;
33 }
34 int main() {
35     pre();
36     scanf("%lld",&n);
37     n++;
38     while(n) {
39         w[++len]=n&1;
40         n>>=1;
41     }
42     LL ans=1LL;
43     for(int i=1;i<=len;i++) ans*=power(i,cnt(i)),ans%=mod;
44     printf("%lld",ans);
45 }
View Code

 




















以上是关于[BZOJ3209]花神的数论题 组合数+快速幂的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3209: 花神的数论题

bzoj3209: 花神的数论题(数位DP)

BZOJ.3209.花神的数论题(数位DP)

bzoj 3209: 花神的数论题 数位dp

BZOJ3209花神的数论题 数位DP

BZOJ 3209 花神的数论题