玄學代碼(是洛谷題解裏的一位dalao小粉兔寫的)ios
//數位DP(二進制)計算出f[i]爲剛好有i個的方案數。 //答案爲∏(i^f[i]),快速冪解決。 #include<bits/stdc++.h> using namespace std; #define ll long long const int mod=10000007; ll n,ans=1; ll c,f[50]; ll qpow(ll b,ll e){ ll a=1; for(;e;b=b*b%mod,e>>=1) e&1?a=a*b%mod:0; return a; } int main(){ scanf("%lld",&n); for(int j=49;~j;--j){ for(int i=49;i;--i) f[i]+=f[i-1]; if(n>>j&1)++f[c++]; }++f[c]; for(int i=1;i<=49;++i) ans=ans*qpow(i,f[i])%mod; printf("%lld",ans); return 0; }
下面是另外一位dalaoStyx寫的簡單易懂的題解c++
代碼以下ui
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #define mod 10000007 using namespace std; long long ans=1,n,k,cnt,dp[110][110]; long long kasumi(long long a,long long b) { long long tmp=1; while(b) { if(b&1) tmp=(tmp%mod)*a%mod; a=(a%mod)*a%mod; b>>=1; } return tmp%mod; } int main() { scanf("%lld",&n); for(int i=1; i<=60; i++) { dp[i][1]=1; } for(int i=1; i<=60; i++) { dp[i][i]=1; } for(int i=2; i<=60; i++) { for(int j=2; j<i; j++) { dp[i][j]=dp[i-1][j-1]+dp[i-1][j]; } } for(k=1; k<=n; k<<=1) { n-=k; cnt++; for(int j=1; j<=cnt; j++) { ans=(ans%mod)*kasumi(j,dp[cnt][j])%mod; ans%=mod; } } cnt=0; for(int i=60;i>=0;i--) { if((1ll<<i)<=n) { for(int j=1;j<=i+1;j++) { ans=(ans%mod)*kasumi(j+cnt,dp[i+1][j]); ans%=mod; } cnt++; n-=(1ll<<i); } } printf("%lld\n",ans); }
至於爲何不用擴展歐拉定理降冪,那是由於楊輝三角在總和等於1e15的時候 ,每個數確定不會爆longlongspa