考虑把 $sum$ 值相同的一起用快速幂计算
枚举 $sum=i$ ,然后可以用数位 $dp$ 求有多少小于 $n$ 的二进制下恰好有 $i$ 个 $1$ 的数的个数
注意不要把个数取模,因为个数是幂次
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=233,mo=10000007; inline ll fk(ll x) { return x>=mo ? x-mo : x; } ll n,C[N][N],ans=1; ll b[N],res; void dfs(int p,int t) { if(!t) { res++; return; } if(!p) return; if(!b[p]) dfs(p-1,t); else res+=C[p-1][t],dfs(p-1,t-1); } ll ksm(ll x,ll y) { ll res=1; while(y) { if(y&1) res=res*x%mo; x=x*x%mo; y>>=1; } return res; } int main() { n=read(); for(int i=0;i<64;i++) { C[i][0]=1; for(int j=1;j<=i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; } int len=0; ll t=n; while(t) b[++len]=t&1,t>>=1; for(int i=1;i<=len;i++) { res=0; dfs(len,i); ans=ans*ksm(i,res)%mo; } printf("%lld ",ans); return 0; }