好题,看出来实际是个堆的种数,忘了组合数。。
/** * Problem:Magic * Author:Shun Yao * Time:2013.6.2 * Result:Accepted * Memo:DP, Math */ #include <cstdio> #include <cmath> const long Maxn = 1000005; long min(long x, long y) { return x < y ? x : y; } long n; long long p, f[Maxn], d[Maxn], jc[Maxn]; void exgcd(long long a, long long b, long long &x, long long &y) { if (!b) { x = 1; y = 0; } else { exgcd(b, a % b, y, x); y -= a / b * x; } } long long mulinv(long long X) { long long x, y; exgcd(X, p, x, y); return ((-x) / p * p + x + p) % p; } int main() { long i, dep, u, l, r; freopen("magic.in", "r", stdin); freopen("magic.out", "w", stdout); scanf("%ld%lld", &n, &p); jc[0] = 1; for (i = 1; i <= n; ++i) jc[i] = jc[i - 1] * i % p; f[0] = f[1] = d[0] = d[1] = 1 % p; for (i = 2; i <= n; ++i) { dep = (long)(log(i) / log(2) + 1e-10); u = (long)(pow(2.0, dep) + 1e-10) - 1; l = ((u - 1) >> 1) + min(i - u, ((u + 1) >> 1)); r = i - 1 - l; f[i] = f[l] * f[r] % p * jc[i - 1] % p; d[i] = d[l] * d[r] % p * jc[l] % p * jc[r] % p; } printf("%lld", f[n] * mulinv(d[n]) % p); fclose(stdin); fclose(stdout); return 0; }