[数位DP] BZOJ 3209 花神的数论题
2016-08-23 18:25
330 查看
求出有i个1的数有多少
然后快速幂
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100005;
const int M=255;
const int P=10000007;
ll a
,len,n;
ll C[M][M];
inline void Pre(){
for(int i=0;i<60;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 ll Solve(ll k){
ll ans=0;
for(ll i=len;i>=1;i--){
if(a[i])
ans+=C[i-1][k],k--;
if(k<0) return ans;
}
return ans;
}
inline ll Pow(ll a,ll b){
ll ret=1; a%=P;
for (;b;b>>=1,a=a*a%P)
if (b&1)
ret=ret*a%P;
return ret;
}
int main()
{
Pre();
scanf("%lld",&n);
n++; len=0;
while (n) a[++len]=n%2,n>>=1;
ll ans=1;
for(int i=1;i<=len;i++)
ans=ans*Pow(i,Solve(i))%P;
printf("%lld\n",ans);
return 0;
}
然后快速幂
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100005;
const int M=255;
const int P=10000007;
ll a
,len,n;
ll C[M][M];
inline void Pre(){
for(int i=0;i<60;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 ll Solve(ll k){
ll ans=0;
for(ll i=len;i>=1;i--){
if(a[i])
ans+=C[i-1][k],k--;
if(k<0) return ans;
}
return ans;
}
inline ll Pow(ll a,ll b){
ll ret=1; a%=P;
for (;b;b>>=1,a=a*a%P)
if (b&1)
ret=ret*a%P;
return ret;
}
int main()
{
Pre();
scanf("%lld",&n);
n++; len=0;
while (n) a[++len]=n%2,n>>=1;
ll ans=1;
for(int i=1;i<=len;i++)
ans=ans*Pow(i,Solve(i))%P;
printf("%lld\n",ans);
return 0;
}
相关文章推荐
- BZOJ_3209_花神的数论题_组合数+数位DP
- [Bzoj3209]花神的数论题(数位dp)
- BZOJ 3209: 花神的数论题【数位dp】
- 【BZOJ3209】花神的数论题 数位DP
- [数位dp] bzoj 3209 花神的数论题
- bzoj 3209: 花神的数论题【数位dp】
- BZOJ 3209: 花神的数论题 (数位dp)
- bzoj 3209 花神的数论题(数位dp)
- bzoj 3209: 花神的数论题 数位dp
- 【bzoj3209】花神的数论题 数位DP
- [bzoj3209]花神的数论题_数位dp
- [BZOJ3209]花神的数论题(数位dp)
- bzoj 3209: 花神的数论题 数位dp
- BZOJ 3209 花神的数论题 数位dp
- [BZOJ]3209: 花神的数论题 数位DP
- [BZOJ3209]花神的数论题(数位dp)
- bzoj3209 花神的数论题 数位DP
- bzoj 3209: 花神的数论题 (数位DP)
- BZOJ3209 花神的数论题(数位dp)
- BZOJ 3209: 花神的数论题 (数位dp)