基於LAMP環境,搭建zabbix環境
阿新 • • 發佈:2022-04-13
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #define clr(f, n) memset(f, 0, sizeof(int) * (n)) #define cpy(f, g, n) memcpy(f, g, sizeof(int) * (n)) using namespace std; const int _G = 3, MOD = 998244353, N = 1 << 20 | 500; int n, m, tr[N << 1], tf; long long quickPower (long long x, long long y) { long long res = 1; while (y) { if (y & 1) res = res * x % MOD; x = x * x % MOD; y >>= 1; } return res; } const int invG = quickPower(_G, MOD - 2); inline void tpre (int n) { if (tf == n) return; tf = n; for (int i = 0; i < n; i ++) tr[i] = tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0); } inline void ntt (int *g, bool op, int n) { tpre(n); static unsigned long long f[N << 1], w[N << 1] = {1}; for (int i = 0; i < n; i ++) f[i] = (((long long) MOD << 5) + g[tr[i]]) % MOD; for (int l = 1; l < n; l <<= 1) { unsigned long long tG = quickPower(op ? _G : invG, (MOD - 1) / (l + l)); for (int i = 1; i < l; i ++) w[i] = w[i - 1] * tG % MOD; for (int k = 0; k < n; k += l + l) for (int p = 0; p < l; p ++) { unsigned long long tt = w[p] * f[k | l | p] % MOD; f[k | l | p] = f[k | p] + MOD - tt; f[k | p] += tt; } if (l == (1 << 10)) for (int i = 0; i < n; i ++) f[i] %= MOD; } if (!op) { unsigned long long invn = quickPower(n, MOD - 2); for (int i = 0; i < n; i ++) g[i] = f[i] % MOD * invn % MOD; } else for (int i = 0; i < n; i ++) g[i] = f[i] % MOD; } inline void px (int *f, int *g, int n) { for (int i = 0; i < n; i ++) f[i] = 1ll * f[i] * g[i] % MOD; } #define Poly vector<int> Poly operator + (const Poly &A, const Poly &B) { Poly C = A; C.resize(max(A.size(), B.size())); for (int i = 0; i < B.size(); i ++) C[i] = (C[i] + B[i]) % MOD; return C; } Poly operator - (const Poly &A, const Poly &B) { Poly C = A; C.resize(max(A.size(), B.size())); for (int i = 0; i < B.size(); i ++) C[i] = (C[i] + MOD - B[i]) % MOD; return C; } Poly operator * (const int c, const Poly &A) { Poly C; C.resize(A.size()); for (int i = 0; i < A.size(); i ++) C[i] = 1ll * c * A[i] % MOD; return C; } int lim; Poly operator * (const Poly &A, const Poly &B) { static int a[N << 1], b[N << 1]; cpy(a, &A[0], A.size()); cpy(b, &B[0], B.size()); Poly C; C.resize(min(lim, (int)(A.size() + B.size() - 1))); int n = 1; for (n; n < A.size() + B.size() - 1; n <<= 1); ntt(a, 1, n); ntt(b, 1, n); px(a, b, n); ntt(a, 0, n); cpy(&C[0], a, C.size()); clr(a, n); clr(b, n); return C; } inline void pinv (const Poly &A, Poly &B, int n) { if (n == 1) B.push_back(quickPower(A[0], MOD - 2)); else if (n & 1) { pinv(A, B, -- n); int sav = 0; for (int i = 0; i < n; i ++) sav = (sav + 1ll * B[i] * A[n - i]) % MOD; B.push_back(1ll * sav * quickPower(MOD - A[0], MOD - 2) % MOD); } else { pinv(A, B, n / 2); Poly sA; sA.resize(n); cpy(&sA[0], &A[0], n); B = 2 * B - B * B * sA; B.resize(n); } } //多項式乘法逆元 Poly pinv (const Poly &A) { Poly C; pinv(A, C, A.size()); return C; } int inv[N]; inline void Init () { inv[1] = 1; for (int i = 2; i <= lim; i ++) inv[i] = 1ll * inv[MOD % i] * (MOD - MOD / i) % MOD; } //多項式求導 Poly dao (const Poly &A) { Poly C = A; for (int i = 1; i < C.size(); i ++) C[i - 1] = 1ll * C[i] * i % MOD; C.pop_back(); return C; } //多項式積分 Poly ints (const Poly &A) { Poly C = A; for (int i = C.size() - 1; i; i --) C[i] = 1ll * C[i - 1] * inv[i] % MOD; C[0] = 0; return C; } //多項式ln Poly ln (const Poly &A) { return ints(dao(A) * pinv(A)); } inline void pexp (const Poly &A, Poly &B, int n) { if (n == 1) B.push_back(1); else if (n & 1) { pexp(A, B, n - 1); n -= 2; int sav = 0; for (int i = 0; i <= n; i ++) sav = (sav + 1ll * (i + 1) * A[i + 1] % MOD * B[n - i]) % MOD; B.push_back(1ll * sav * inv[n + 1] % MOD); } else { pexp(A, B, n / 2); Poly lnB = B; lnB.resize(n); lnB = ln(lnB); for (int i = 0; i < lnB.size(); i ++) lnB[i] = (MOD + A[i] - lnB[i]) % MOD; lnB[0] ++; B = B * lnB; B.resize(n); } } //多項式exp Poly pexp (const Poly &A) { Poly C; pexp(A, C, A.size()); return C; } Poly F, G; int main () { scanf("%d%d", &n, &m); F.resize(n + 1); G.resize(m + 1); lim = n + m + 1; for (int i = 0; i <= n; i ++) scanf("%d", &F[i]); for (int i = 0; i <= m; i ++) scanf("%d", &G[i]); F = F * G; for (int i = 0; i < F.size(); i ++) printf("%d ", F[i]); return 0; }