多项式除法 90pts 代码求调
查看原帖
多项式除法 90pts 代码求调
109114
_l_l_¯l¯l¯楼主2022/6/9 08:08

如标题,第 5 测试点 WA。

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1 << 22;
template<const int MAXL, const int mod> class NTT {
	inline static int add(int x, const int y) {
		x += y;
		if (x >= mod) x -= mod;
		return x;
	}
	inline int sub(int x, const int y) {
		x -= y;
		if (x < 0) x += mod;
		return x;
	}
	inline int qkpow(int a, int b) {
		int ans = 1;
		for (; b; b >>= 1, a = 1ll * a * a % mod) {
			if (b & 1) ans = 1ll * ans * a % mod;
		}
		return ans;
	}
	const int g = 3, invg = qkpow(g, mod - 2);
	int rev[MAXL], wpre[MAXL];
	int F[MAXL], G[MAXL], H[MAXL];
	public:
	inline int prev_(const int *a, const int n, const int LL) {
		int L = 1, lL = 0;
		while (L <= LL) L <<= 1, lL++; 
		for (int i = 0; i < L; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1) << (lL - 1);
		for (int i = 0; i <= n; i++) F[i] = a[i];
		for (int i = n + 1; i < L; i++) F[i] = 0; 
		return L;
	}
	inline int prev_(const int *a, const int *b, const int n, const int m, const int LL) {
		const int L = prev_(a, n, LL);
		for (int i = 0; i <= m; i++) G[i] = b[i];
		for (int i = m + 1; i < L; i++) G[i] = 0;
		return L; 
	}
	inline int prev_(const int *a, const int *b, const int *c, const int n, const int m, const int k, const int LL) {
		const int L = prev_(a, b, n, m, LL);
		for (int i = 0; i <= k; i++) H[i] = c[i];
		for (int i = k + 1; i < L; i++) H[i] = 0;
		return L; 
	}
	inline void DFT(int *a, const int L, const bool op) {
		wpre[0] = 1;
		for (int i = 0; i < L; i++) if (i < rev[i]) swap(a[i], a[rev[i]]);
		for (int len = 1; len < L; len <<= 1) {
			int w0 = qkpow(op ? g : invg, (mod - 1) / len >> 1);
			for (int i = 1; i < len; i++) wpre[i] = 1ll * wpre[i - 1] * w0 % mod;
			for (int l = 0; l < L; l += len << 1) {
				for (int it = l; it < l + len; it++) {
					int x = a[it], y = 1ll * a[it + len] * wpre[it - l] % mod;
					a[it] = add(x, y); a[it + len] = sub(x, y);
		}	}	}
		if (op) {
			int invL = qkpow(L, mod - 2);
			for (int i = 0; i < L; i++) a[i] = 1ll * a[i] * invL % mod;
		}
	}
	inline void inv(const int n, const int *a, int *b) {
		if (n == 0) {
			if (a[0] == 0) b[0] = 1 / (a[0] - a[0]);
			b[0] = qkpow(a[0], mod - 2);
			return;
		}
		inv(n >> 1, a, b);
		int L = prev_(a, b, n, n >> 1, n + (n >> 1));
		DFT(F, L, 0);
		DFT(G, L, 0);
		for (int i = 0; i < L; i++) F[i] = (2ll * G[i] + 1ll * mod * mod - 1ll * F[i] * G[i] % mod * G[i]) % mod;
		DFT(F, L, 1);
		for (int i = 0; i <= n; i++) b[i] = F[i];
	}
    inline void div(const int n, const int m, const int *a, const int *b, int *q, int *r) {
        static int tmp1[MAXL], tmp2[MAXL], tmp3[MAXL];
        for (int i = 0; i <= m; i++) tmp2[i] = b[m - i];
        for (int i = m + 1; i <= n; i++) tmp2[i] = 0;
        inv(n, tmp2, tmp3);
        for (int i = 0; i <= n; i++) tmp2[i] = a[n - i];
        int L = prev_(tmp2, tmp3, n, n, n << 1);
        DFT(F, L, 0);
        DFT(G, L, 0);
        for (int i = 0; i < L; i++) tmp2[i] = 1ll * F[i] * G[i] % mod;
        DFT(tmp2, L, 1);
        for (int i = 0; i <= n - m; i++) q[n - m - i] = tmp2[i];
        for (int i = 0; i <= n - m; i++) tmp2[i] = q[i];
        for (int i = 0; i <= n; i++) tmp1[i] = a[i];
        for (int i = 0; i <= m; i++) tmp3[i] = b[i];
        L = prev_(tmp1, tmp2, tmp3, n, n - m, m, n << 1);
        DFT(F, L, 0);
        DFT(G, L, 0);
        DFT(H, L, 0);
        for (int i = 0; i < L; i++) F[i] = (F[i] + 1ll * mod * mod - 1ll * G[i] * H[i]) % mod;
        DFT(F, L, 1);
        for (int i = 0; i < m; i++) r[i] = F[i];
    }
};
NTT<MAXN, 998244353> ntt;
int a[MAXN], b[MAXN], q[MAXN], r[MAXN];
int main() {
	int n, m;
	scanf("%d %d", &n, &m);
    for (int i = 0; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 0; i <= m; i++) scanf("%d", &b[i]);
    ntt.div(n, m, a, b, q, r);
    for (int i = 0; i <= n - m; i++) printf("%d%c", q[i], " \n"[i == n - m]);
    for (int i = 0; i < m; i++) printf("%d%c", r[i], " \n"[i == m - 1]);
	return 0;
}
2022/6/9 08:08
加载中...