花神的數論題
阿新 • • 發佈:2019-01-05
Title Link
Title Solution
這道題可以運用組合數的思想啊,數位dp也可以,隨便你怎麼做,這裡就講一講組合數的做法吧,要小於n,所以我們可以列舉n二進位制下1的位置,在i-1後面選j個1.用組合數做一下就好了啊
code
#include<bits/stdc++.h> #define int long long using namespace std; const int mod=10000007; int c[1011][1011],f[101]; int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x*f; } void init(){ for(int i=0;i<=1000;i++) c[i][i]=c[i][0]=1; for(int i=2;i<=1000;i++) for(int j=1;j<i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1]; } int ksm(int a,int b){ int ans=1; while(b){ if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } main(){ int n=read(),ans=1,js=0; init(); for(int i=50;i>=0;i--){ if((n>>i)&1){ for(int j=1;j<=i;j++) f[js+j]+=c[i][j]; f[++js]++; } } for(int i=1;i<=50;i++) ans*=ksm(i,f[i]),ans%=mod; printf("%lld",ans); }