题目
题目链接:https://www.luogu.com.cn/problem/P4317
话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。 花神的题目是这样的:设 \(\text{sum}(i)\) 表示 \(i\) 的二进制表示中 \(1\) 的个数。给出一个正整数 \(N\) ,花神要问你 \(\prod_{i=1}^{N}\text{sum}(i)\) ,也就是 \(\text{sum}(1)\sim\text{sum}(N)\) 的乘积。
思路
设 \(f(i)\) 为有 \(i\) 个一的方案数。可以用组合数乱搞搞出。
答案即为
\[\Pi^{\log n}_{i=1} i^{f(i)}
\]
时间复杂度 \(O(\log^2 n)\)。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=10000007,LG=55;
ll n,cnt,ans,f[LG+1],C[LG+1][LG+1];
ll fpow(ll x,ll k)
{
ll ans=1;
for (;k;k>>=1,x=x*x%MOD)
if (k&1) ans=ans*x%MOD;
return ans;
}
int main()
{
C[1][0]=C[1][1]=1;
for (int i=2;i<=LG;i++)
for (int j=0;j<=i;j++)
C[i][j]=C[i-1][j]+C[i-1][j-1];
scanf("%lld",&n);
for (int i=LG;i>=0;i--)
if (n&(1LL<<i))
{
for (int j=1;j<=i;j++) f[j+cnt]+=C[i][j];
cnt++; f[cnt]++;
}
ans=1;
for (int i=1;i<=LG;i++)
ans=ans*fpow(i,f[i])%MOD;
printf("%lld",ans);
return 0;
}