1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #include<bits/stdc++.h> #define int long long using namespace std; template <class T> inline void read(T &res) { res = 0; bool flag = 0; char c = getchar(); while('0' > c || c > '9') { if(c == '-') flag = 1; c = getchar();} while('0' <= c && c <= '9') res = (res << 3) + (res << 1) + (c ^ 48), c = getchar(); if(flag) res = -res; } template <class T, class ...Arg> inline void read(T &res, Arg &...com){ read(res), read(com...);} template <class T> void write(T res) { if(res > 9) write(res / 10); putchar(res % 10 + '0'); } const int N = 4e5 + 5, mod = 1004535809; int n; int fac[N], inv[N]; inline int qpow(int x, int k) { int res = 1; while(k) { if(k & 1) res = res * x % mod; x = x * x % mod; k >>= 1; } return res; } inline void init() { fac[0] = inv[0] = fac[1] = inv[1] = 1; for(int i = 2;i < N;i ++) fac[i] = i * fac[i - 1] % mod, inv[i] = (mod - mod / i) * inv[mod % i] % mod; for(int i = 2;i < N;i ++) inv[i] = inv[i] * inv[i - 1] % mod; } int f[N], g[N], H[N], le[N]; int tot, bit; int r[N]; inline void calc(int bit) { for(int i = 0;i < (1 << bit);i ++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (bit - 1)); } inline void NTT(int x[], int bit, int op) { calc(bit); int tot = 1 << bit; for(int i = 0;i < tot;i ++) if(i < r[i]) swap(x[i], x[r[i]]); for(int mid = 1, len, gn; mid < tot; mid <<= 1) { len = mid << 1; gn = qpow(3, (mod - 1) / len); if(~op) gn = qpow(gn, mod - 2); for(int i = 0;i < tot;i += len) for(int j = 0, a, b, g = 1;j < mid;j ++, g = g * gn % mod) { a = x[i + j], b = g * x[i + j + mid] % mod; x[i + j] = (a + b) % mod; x[i + j + mid] = (a - b + mod) % mod; } } if(~op) return ; op = qpow(tot, mod - 2); for(int i = 0;i < tot;i ++) x[i] = x[i] * op % mod; } inline int Mod(int x) { return (x %= mod) < 0 ? x + mod : x; } inline void get_inv(int len, int a[], int b[]) { static int c[N]; if(len == 1) return b[0] = qpow(a[0], mod - 2), void(); get_inv(len >> 1, a, b); int bit = 0, tot; while((1 << bit) < (len << 1)) bit ++; tot = (1 << bit); for(int i = 0;i < tot;i ++) if(i < len) c[i] = a[i]; else c[i] = 0; NTT(c, bit, 1), NTT(b, bit, 1); for(int i = 0;i < tot;i ++) b[i] = Mod(Mod(2ll - c[i] * b[i] % mod) * b[i]); NTT(b, bit, -1); for(int i = len;i < tot;i ++) b[i] = 0; } signed main() { init(); read(n); tot = 1; while(tot <= n) tot <<= 1, bit ++; for(int i = 1;i <= n;i ++) H[i] = qpow(2, i * (i - 1) / 2) * inv[i - 1] % mod; for(int i = 0;i <= n;i ++) g[i] = inv[i] * qpow(2, i * (i - 1) / 2) % mod; get_inv(tot, g, le); NTT(H, bit, 1), NTT(le, bit, 1); for(int i = 0;i < tot;i ++) f[i] = H[i] * le[i] % mod; NTT(f, bit, -1); write(f[n] * fac[n - 1] % mod); return 0; }
|