题目链接:BZOJ 3209
10000007不是质数。10000007=941*10627。用费马小定理的请注意。
组合数
1.组合恒等式:C(n,m)= C(n,n-m)= C(n-1,m-1)+C(n-1,m)
2.全组合数求和:sigma(c(N,i)) (i->0...N) = 2^N
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define LL long long
#define mod (10000007)
LL N;
int a[1000];
LL f[100][100];
LL num[100];
void init(){//f[i][j]:descrip int the digit i,the kinds of number that has j 1.
for(int i=0;i<=66;i++)f[i][0]=1;
for(int i=1;i<=66;i++)
for(int j=1;j<=i;j++)
f[i][j]=f[i-1][j]+f[i-1][j-1];
}
void get(int l){
int tot=0;
for(int i=l;i>=1;i--){
if(a[i]){//if the number in this position is 1,it can update the answer.
tot++;
for(int j=0;j<i;j++){
num[j+tot-1]+=f[i-1][j];
}
}
}
}
LL pow(LL x,LL y){//quick power ,but be careful that we should use long long.
LL t=1;
while(y){
if(y&1)t=(t*x)%mod;
y>>=1;
x=(x*x)%mod;
}
return t;
}
void find(){
LL t=N;
int len=0;
while(t){
a[++len]=t%2; t>>=1;
}
get(len);
LL ans=1;
for(int i=1;i<=66;i++){//the answer is sigma(i^ans[i]).
ans=(ans*pow(i,num[i]))%mod;
}
cout<<ans<<endl;
}
int main(){
init();
cin>>N;
N++;
find();
return 0;
}