mset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
}
void Inv(int *a, int *b, int len) {//B1 = 2B - A1 * B^2
if(len == 1) {b[0] = fp(a[0], mod - 2); return ;}
Inv(a, b, len >> 1);
for(int i = 0; i < len; i++) A[i] = a[i], B[i] = b[i];
NTT(A, len << 1, 1); NTT(B, len << 1, 1);
for(int i = 0; i < (len << 1); i++) mul2(A[i], mul(B[i], B[i]));
NTT(A, len << 1, -1);
for(int i = 0; i < len; i++) add2(b[i], add(b[i], -A[i]));
for(int i = 0; i < (len << 1); i++) A[i] = B[i] = 0;
}
void Dao(int *a, int *b, int len) {
for(int i = 1; i < len; i++) b[i - 1] = mul(i, a[i]); b[len - 1] = 0;
}
void Ji(int *a, int *b, int len) {
for(int i = 1; i < len; i++) b[i] = mul(a[i - 1], fp(i, mod - 2)); b[0] = 0;
}
void Ln(int *a, int *b, int len) {//G(A) = \frac{A}{A'} qiudao zhihou jifen
static int A[MAXN], B[MAXN];
Dao(a, A, len);
Inv(a, B, len);
NTT(A, len << 1, 1); NTT(B, len << 1, 1);
for(int i = 0; i < (len << 1); i++) B[i] = mul(A[i], B[i]);
NTT(B, len << 1, -1);
Ji(B, b, len << 1);
memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
}
void Exp(int *a, int *b, int len) {//F(x) = F_0 (1 - lnF_0 + A) but code ..why....
if(len == 1) return (void) (b[0] = 1);
Exp(a, b, len >> 1); Ln(b, C, len);
C[0] = add(a[0] + 1, -C[0]);
for(int i = 1; i < len; i++) C[i] = add(a[i], -C[i]);
NTT(C, len << 1, 1); NTT(b, len << 1, 1);
for(int i = 0; i < (len << 1); i++) mul2(b[i], C[i]);
NTT(b, len << 1, -1);
for(int i = len; i < (len << 1); i++) C[i] = b[i] = 0;
}
void Sqrt(int *a, int *b, int len) {
static int B[MAXN];
Ln(a, B, len);
for(int i = 0; i < len; i++) B[i] = mul(B[i], INV2);
Exp(B, b, len);
}
};
using namespace Poly;
signed main() {
N = read(); int Lim = GetLen(N); Init(4 * Lim);
fac[0] = 1;
for(int i = 1; i <= N; i++) fac[i] = mul(i, fac[i - 1]);
ifac[N] = fp(fac[N], mod - 2);
for(int i = N; i >= 1; i--) ifac[i - 1] = mul(i, ifac[i]);
for(int i = N; i >= 1; i--) {
int tmp;
if(i & 1) tmp = fp(2, 1ll * ((i - 1) / 2) * i % mod2);
else tmp = fp(2, 1ll * (i / 2) * (i - 1) % mod2);
a[i] = mul(tmp, ifac[i - 1]),
b[i] = mul(tmp, ifac[i]);
}
b[0] = 1;
Inv(b, c, Lim);
Mul(a, c, Lim, Lim);
cout << mul(c[N], fac[N - 1]);
return 0;
}
|