bzoj 3209 数位DP+欧拉定理

 

枚举1的个数,统计有那么多1的数的个数

 

 1 /**************************************************************
 2     Problem: 3209
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:0 ms
 7     Memory:844 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #define Mod 10000007
12 #define Phi 9988440
13  
14 typedef long long dnt;
15  
16 dnt n;
17 dnt dp[50][2][51];
18 int tb;
19  
20 void dodp() {
21     for( tb=49; tb>=0; tb-- )
22         if( (n>>tb)&1 ) break;
23     dp[tb][1][1] = 1;
24     dp[tb][0][0] = 1;
25     for( int b=tb-1; b>=0; b-- ) {
26         for( int c=0; c<=tb-b+1; c++ ) {
27             dp[b][1][c] = dp[b+1][1][c-((n>>b)&1)];
28             dp[b][0][c] = (dp[b+1][0][c] + dp[b+1][0][c-1]) % Phi;
29             if( (n>>b)&1 ) dp[b][0][c] = (dp[b][0][c] + dp[b+1][1][c]) % Phi;
30         }
31     }
32 }
33 dnt mpow( dnt a, dnt b ) {
34     dnt rt;
35     for( rt=1; b; b>>=1,a=(a*a)%Mod )
36         if( b&1 ) rt=(rt*a)%Mod;
37     return rt;
38 }
39 int main() {
40     scanf( "%lld", &n );
41     dodp();
42     dnt ans = 1;
43     for( int c=2; c<=tb+1; c++ )
44         ans = (ans * mpow(c,dp[0][1][c]+dp[0][0][c])) % Mod;
45     printf( "%lld\n", ans );
46 }
View Code

 

posted @ 2015-06-06 19:47  idy002  阅读(197)  评论(0编辑  收藏  举报