3209: 花神的数论题
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1148 Solved: 535
[ 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
3
Sample Output
样例输出一
2
2
HINT
对于样例一,1*1*2=2;
数据范围与约定
对于 100% 的数据,N≤10^15
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define bug printf("hihi\n")
#define eps 1e-8
typedef long long ll;
using namespace std;
#define N 65
#define mod 10000007
ll dp[N][N];
ll n,bit[N];
ll dfs(int pos,int k,bool bound)
{
if(pos==0) return k ? k:1;
if(!bound&&dp[pos][k]>=0) return dp[pos][k];
ll ans=1;
if(bound)
{
if(bit[pos])
{
ans=ans*dfs(pos-1,k,false)%mod;
ans=ans*dfs(pos-1,k+1,bound)%mod;
}
else
{
ans=ans*dfs(pos-1,k,bound)%mod;
}
}
else
{
ans=ans*dfs(pos-1,k,false)%mod;
ans=ans*dfs(pos-1,k+1,false)%mod;
}
if(!bound) dp[pos][k]=ans;
return ans;
}
ll solve()
{
int i,j;
int len=0;
while(n)
{
bit[++len]=n%2;
n>>=1;
}
return dfs(len,0,true);
}
int main()
{
int i,j;
memset(dp,-1,sizeof(dp));
while(~scanf("%lld",&n))
{
printf("%lld\n",solve());
}
return 0;
}