正题
题目链接:https://www.luogu.com.cn/problem/P4317
题目大意
定义sum(i)sum(i)sum(i)表示iii二进制下111的个数
求∏i=1nsum(i)\prod_{i=1}^nsum(i)i=1∏nsum(i)
解题思路
考虑计算有iii个111的有多少个数字。
对于nnn的每一个111,我们可以知道如果这一位为000那么就可以用组合数学快速计算。
所以我们枚举个jjj表示固定前jjj位为最大值然后用组合数学计算。
时间复杂度O(log2n)O(\log^2 n)O(log2n)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll XJQ=10000007;
ll n,c[100][100],ans;
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%XJQ;x=x*x%XJQ;b>>=1; }return ans;
}
int main()
{scanf("%lld",&n);ans=c[0][0]=1;for(ll i=1;i<=55;i++){c[i][0]=1;for(ll j=1;j<=i;j++)c[i][j]=c[i-1][j-1]+c[i-1][j];}ll x=n,z=0;while(x)x-=x&-x,z++;for(ll i=1;i<56;i++){ll k=0,now=0;for(ll j=55;j>=0;j--){if((n>>j)&1){k+=c[j][i-now];now++;}if(now>i)break;}k+=(z==i);ans=ans*power(i,k)%XJQ;}printf("%lld",ans);
}