题目链接: BZOJ - 3209
题目大意
设 f(x) 为 x 的二进制表示中 1 的个数。给定 n ,求 ∏ f(i) (1 <= i <= n) 。
题目分析
总体思路是枚举每一个 t ,算出 f(x) = t 的 x 有 y 个,然后将 t^y 算入答案中。
主要的过程是求 y ,也就是代码中的 Solve(t) 。
详见代码吧,我只能看别人的题解,自己想不出来QAQ
注意:WA警告!WA警告!
Warning!Warning!Warning!
在涉及到计算 a^b%p 的计算中,a 可以先 mod p ,但是 b 不可以!!!计算 b 的时候,因为 b 之后要作为指数,所以绝对不能取模!!!!!
在这道题中,组合数不能取模!!!Solve() 不能取模!!!因为这些都与指数有关!!
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MaxL = 60 + 5;
const LL Mod = 10000007;
LL n, Ans;
LL C[MaxL][MaxL];
int l, Bit[MaxL];
void Init_C() {
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 - 1] + C[i - 1][j];
}
}
LL Solve(int x) {
LL ret = 0;
for (int i = l; i >= 1; --i) {
if (Bit[i] == 1) {
ret += C[i - 1][x];
--x;
}
if (x < 0) break;
}
return ret;
}
LL Pow(LL a, LL b) {
LL ret = 1, f = a % Mod;
while (b) {
if (b & 1) {
ret *= f;
ret %= Mod;
}
b >>= 1;
f *= f;
f %= Mod;
}
return ret;
}
int main()
{
Init_C();
while (scanf("%lld", &n) != EOF) {
++n;
l = 0;
while (n) {
Bit[++l] = n & 1;
n >>= 1;
}
Ans = 1ll;
for (int i = 1; i <= l; ++i)
Ans = Ans * Pow(i, Solve(i)) % Mod;
printf("%lld
", Ans);
}
return 0;
}