您的位置:首页 > 其它

【bzoj 3209】花神的数论题(组合数学)

2018-01-26 11:44 489 查看
传送门biu~

令aniani代表二进制中11的个数为ii的数有多少个。从高位向低位枚举,假设输入的数nn的二进制第ii位为11,那么设一个数xx的第ii位为00,前i−1i−1位与nn相同,那么无论比ii位低的数位中哪一位为11,xx都不会大于nn,所以可以用组合数Cki−1Ci−1k更新答案。

Ps:φ(10000007)=9988440φ(10000007)=9988440

说得不清楚看代码:

#include<bits/stdc++.h>
using namespace std;
const long long mod=10000007,phi=9988440;
long long n,ans=1;
long long c[51][51],an[51];
int a[51],now,cnt;
inline void getC(){
for(int i=0;i<=50;++i){
c[i][0]=1;
for(int j=1;j<=i;++j)  c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
inline long long ksm(long long p,long long n){
long long re=1;
while(n){
if(n&1) re=re*p%mod;
p=p*p%mod;
n>>=1;
}
return re;
}
int main(){
scanf("%lld",&n);
getC();
while(n){a[++cnt]=n&1;n>>=1;}
for(int i=cnt;i>=1;--i){
if(!a[i])   continue;
for(int j=1;j<i;++j)    an[now+j]+=c[i-1][j];
++an[++now];
}
for(int i=1;i<=cnt;++i)     (ans*=ksm(i,an[i]%phi))%=mod;
printf("%lld",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: