链接:点击打开链接
题意:话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。 花神的题目是这样的:设 表示
的二进制表示中
的个数。给出一个正整数
,花神要问你
,也就是
的乘积。
代码:
#include
using namespace std;
typedef long long ll;
const ll mod=10000007;
ll t,a[55],dp[55][55];
ll dfs(ll pos,ll sum,ll lim){
ll i,u,ans=0;
if(pos==0)
return sum==t;
if(lim==0&&dp[pos][sum]!=-1)
return dp[pos][sum];
u=lim?a[pos]:1;
for(i=0;i<=u;i++){
if(i==0)
ans=(ans+dfs(pos-1,sum,lim&(i==u)));
else if(sum+1<=t)
ans=(ans+dfs(pos-1,sum+1,lim&(i==u)));
}
if(lim==0)
dp[pos][sum]=ans;
return ans;
}
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll cal(ll x){
ll u,ans,pos;
ans=1,pos=0;
while(x){
a[++pos]=x&1;
x>>=1;
}
for(t=1;t<=pos;t++){ //二进制中的1最多就pos个
memset(dp,-1,sizeof(dp));
u=dfs(pos,0,1);
ans=(ans*qpow(t,u))%mod;
}
return ans;
} //枚举二进制中1的个数,然后数位dp,最后直接快速幂算出个数
int main(){
ll r;
scanf("%lld",&r);
printf("%lld\n",cal(r));
return 0;
}