3209: 花神的数论题
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1148 Solved: 535
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
#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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-11 00:31:01