您的位置:首页 > 其它

(bzoj 3209 花神的数论题)<>

2017-08-10 19:15 417 查看
传送门

Solution

将数字看成二进制

f[i][j]表示前i为中有j个1的数的总数

f[i][j]=f[i−1][j−1]+f[i−1][j]

然后逐位统计即可

Code

// by spli
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;

const LL p=10000007;
LL n;
LL f[70][70];
int bit[70],num=0;

LL exp(LL a,LL b){
LL ret=1,k=a%p;
while(b){
if(b&1) (ret*=k)%=p;
b>>=1;
(k*=k)%=p;
}
return ret%p;
}

LL get(int x){
LL s=0;
for(int i=num;i>=1;--i){
if(bit[i]==1){
s+=f[i-1][x];
x--;
}
if(x<0) break;
}
return s;
}

int main(){
scanf("%lld",&n);
n++;
for(int i=0;i<=60;++i) f[i][0]=1;
for(int i=1;i<=60;++i)
for(int j=1;j<=i;++j)
f[i][j]=f[i-1][j]+f[i-1][j-1];//取模会WA
while(n){
bit[++num]=n&1;
n>>=1;
}
LL ans=1;
for(int i=1;i<=num;++i)
(ans*=exp((LL)i,get(i)))%=p;
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: