首先这道题目不难想到将答案转化为这种形式

2^s[2]*3*s[3]*…max*s[max]

这时候我们要分类讨论,设n的二进制位数为t

当1~n中二进制位数小于t时

我们可以直接用组合的知识,二进制有i个1一共有c(t-1,i)

当1~n中二进制位数等于t时

我们数位统计一下即可,具体的当第i位为1时,(从右往左标)

后面i-1位01情况随意,即s[j+s]=s[j+s]+c(i-1,j) (s为到第i位n所含1的个数(不包括第i位),0<=j<=i-1)

当第i位为0,不管他……

最后用一下快速幂即可

 1 const mo=10000007;
 2 
 3 var c:array[0..64,0..64] of int64;
 4     sum:array[0..64] of int64;
 5     b:array[0..64] of int64;
 6     i,j:longint;
 7     n,s,p,t,ans:int64;
 8 
 9 function quick(x,y:int64):int64;
10   var i:longint;
11       m:int64;
12 
13   begin
14     m:=0;
15     while x<>0 do
16     begin
17       inc(m);
18       b[m]:=x mod 2;
19       x:=x div 2;
20     end;
21     quick:=y;
22     for i:=m-1 downto 1 do
23     begin
24       quick:=quick*quick mod mo;
25       if b[i]=1 then quick:=quick*y mod mo;
26     end;
27   end;
28 
29 begin
30   c[0,0]:=1;
31   for i:=1 to 64 do
32   begin
33     c[i,0]:=1;
34     c[i,i]:=1;
35     for j:=1 to i-1 do
36       c[i,j]:=c[i-1,j]+c[i-1,j-1];
37   end;
38   readln(n);
39   t:=trunc(ln(n)/ln(2))+1;
40   for i:=2 to t-1 do
41     sum[i]:=c[t-1,i];
42   t:=0;
43   while n<>0 do
44   begin
45     inc(t);
46     b[t]:=n mod 2;
47     n:=n div 2;
48   end;
49   s:=1;
50   for i:=t-1 downto 1 do
51     if b[i]=1 then
52     begin
53       for j:=0 to i-1 do
54         sum[j+s]:=sum[j+s]+c[i-1,j];
55       s:=s+1;
56     end;
57 
58   sum[s]:=sum[s]+1; //还有n这个数要统计
59   ans:=1;
60   for i:=2 to t do
61     if sum[i]<>0 then
62       ans:=ans*quick(sum[i],i) mod mo;
63   writeln(ans);
64 end.
View Code

 

posted on 2014-09-05 22:04  acphile  阅读(179)  评论(0编辑  收藏  举报