Problem p02563 (python)

Fixed submission:
class FastModuloTransform():
    def __init__(self, n=2**20, mod=998244353, root=3):
        self.n = n
        self.mod = mod
        self.omega = pow(root, (mod - 1) // n, mod)
        self.rev = pow(self.omega, mod - 2, mod)

    def _bit_reverse_(self, A):
        n = self.n
        m = self.n // 2
        i = 0
        for j in range(0, m, 2):
            if j < i:
                A[i], A[j] = A[j], A[i]
                A[i + m + 1], A[j + m + 1] = A[j + m + 1], A[i + m + 1]
            A[i + 1], A[j + m] = A[j + m], A[i + 1]
            k = m // 2
            i ^= k
            while k > i:
                k //= 2
                i ^= k
        return A

    def _fmt_(self, A, base):
        halfpow = pow(base, self.n // 2, self.mod)
        n = self.n
        m = 1
        while n > 1:
            n //= 2
            w = pow(base, n, self.mod)
            k = 1
            for j in range(m):
                for i in range(j, self.n, 2 * m):
                    u = A[i]
                    v = (A[i + m] * k) % self.mod
                    A[i] = (u + v) % self.mod
                    A[i + m] = (u + v * halfpow) % self.mod
                k = (k * w) % self.mod
            m *= 2
        return A

    def fmt(self, f):
        A = f + [0] * (self.n - len(f))
        self._bit_reverse_(A)
        F = self._fmt_(A, self.omega)
        return F

    def ifmt(self, F):
        A = F + [0] * (self.n - len(F))
        self._bit_reverse_(A)
        nrev = pow(self.n, self.mod - 2, self.mod)
        f = [(e * nrev) % self.mod for e in self._fmt_(A, self.rev)]
        return f

    def convolute(self, f, g):
        F = self.fmt(f)
        G = self.fmt(g)
        H = [(s * t) % self.mod for s, t in zip(F, G)]
        h = self.ifmt(H)
        return h

    def autocorrelation(self, f):
        F = self.fmt(f)
        H = [(s * s) % self.mod for s in F]
        h = self.ifmt(H)
        return h

fmt = FastModuloTransform()

N, M = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

res = fmt.convolute(A, B)[:N + M - 1]

print(*res)

Buggy submission (verdict: Runtime Error):
#Convolution_998244353

MOD = 998244353
ROOT = 3

sum_e = (911660635, 509520358, 369330050, 332049552, 983190778, 123842337, 238493703, 975955924, 603855026, 856644456, 131300601, 842657263, 730768835, 942482514, 806263778, 151565301, 510815449, 503497456, 743006876, 741047443, 56250497, 0, 0, 0, 0, 0, 0, 0, 0, 0)
sum_ie = (86583718, 372528824, 373294451, 645684063, 112220581, 692852209, 155456985, 797128860, 90816748, 860285882, 927414960, 354738543, 109331171, 293255632, 535113200, 308540755, 121186627, 608385704, 438932459, 359477183, 824071951, 0, 0, 0, 0, 0, 0, 0, 0, 0)

def butterfly(arr):
    n = len(arr)
    h = (n - 1).bit_length()
    for ph in range(1, h + 1):
        w = 1 << (ph - 1)
        p = 1 << (h - ph)
        now = 1
        for s in range(w):
            offset = s << (h - ph + 1)
            for i in range(p):
                l = arr[i + offset]
                r = arr[i + offset + p] * now
                arr[i + offset] = (l + r) % MOD
                arr[i + offset + p] = (l - r) % MOD
            now *= self.sum_e[(~s & -~s).bit_length() - 1]
            now %= MOD

def butterfly_inv(arr):
    n = len(arr)
    h = (n - 1).bit_length()
    for ph in range(1, h + 1)[::-1]:
        w = 1 << (ph - 1)
        p = 1 << (h - ph)
        inow = 1
        for s in range(w):
            offset = s << (h - ph + 1)
            for i in range(p):
                l = arr[i + offset]
                r = arr[i + offset + p]
                arr[i + offset] = (l + r) % MOD
                arr[i + offset + p] = (MOD + l - r) * inow % MOD
            inow *= self.sum_ie[(~s & -~s).bit_length() - 1]
            inow %= MOD

def convolution(a, b):
    n = len(a)
    m = len(b)
    if not n or not m: return []
    if min(n, m) <= 50:
        if n < m:
            n, m = m, n
            a, b = b, a
        res = [0] * (n + m - 1)
        for i in range(n):
            for j in range(m):
                res[i + j] += a[i] * b[j]
                res[i + j] %= MOD
        return res
    z = 1 << (n + m - 2).bit_length()
    a += [0] * (z - n)
    b += [0] * (z - m)
    butterfly(a)
    butterfly(b)
    for i in range(z):
        a[i] *= b[i]
        a[i] %= MOD
    butterfly_inv(a)
    a = a[:n + m - 1]
    iz = pow(z, MOD - 2, MOD)
    for i in range(n + m - 1):
        a[i] *= iz
        a[i] %= MOD
    return a

def autocorrelation(a):
    n = len(a)
    if not n: return []
    if n <= 50:
        res = [0] * (2 * n - 1)
        for i in range(n):
            for j in range(n):
                res[i + j] += a[i] * a[j]
                res[i + j] %= MOD
        return res
    z = 1 << (2 * n - 2).bit_length()
    a += [0] * (z - n)
    butterfly(a)
    for i in range(a):
        a[i] *= a[i]
        a[i] %= MOD
    butterfly_inv(a)
    a = a[:2 * n - 1]
    iz = pow(z, MOD - 2, MOD)
    for i in range(2 * n - 1):
        a[i] *= iz
        a[i] %= MOD
    return a

N, M = map(int, input().split())
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

print(*convolution(A, B))

Buggy submission (verdict: Runtime Error):
MOD = 998244353
ROOT = 3

class Convolution_998244353():
    def __init__(self):
        self.first1 = True
        self.first2 = True
        self.sum_e = [0] * 30
        self.sum_ie = [0] * 30

    def inv_gcd(self, a, b):
        a %= b
        if a == 0: return b, 0
        s = b
        t = a
        m0 = 0
        m1 = 1
        while t:
            u = s // t
            s -= t * u
            m0 -= m1 * u
            s, t = t, s
            m0, m1 = m1, m0
        if m0 < 0: m0 += b // s
        return s, m0

    def butterfly(self, arr):
        n = len(arr)
        h = (n - 1).bit_length()
        if self.first1:
            self.first1 = False
            es = [0] * 30
            ies = [0] * 30
            m = MOD - 1
            cnt2 = (m & -m).bit_length() - 1
            e = pow(ROOT, m >> cnt2, MOD)
            ie = pow(e, MOD - 2, MOD)
            for i in range(cnt2 - 1)[::-1]:
                es[i] = e
                ies[i] = ie
                e *= e
                e %= MOD
                ie *= ie
                ie %= MOD
            now = 1
            for i in range(cnt2 - 2):
                self.sum_e[i] = es[i] * now % MOD
                now *= ies[i]
                now %= MOD
        for ph in range(1, h + 1):
            w = 1 << (ph - 1)
            p = 1 << (h - ph)
            now = 1
            for s in range(w):
                offset = s << (h - ph + 1)
                for i in range(p):
                    l = arr[i + offset]
                    r = arr[i + offset + p] * now
                    arr[i + offset] = (l + r) % MOD
                    arr[i + offset + p] = (l - r) % MOD
                now *= self.sum_e[(~s & -~s).bit_length() - 1]
                now %= MOD

    def butterfly_inv(self, arr):
        g = self.root
        n = len(arr)
        h = (n - 1).bit_length()
        if self.first2:
            self.first2 = False
            es = [0] * 30
            ies = [0] * 30
            m = MOD - 1
            cnt2 = (m & -m).bit_length() - 1
            e = pow(ROOT, m >> cnt2, MOD)
            ie = pow(e, MOD - 2, MOD)
            for i in range(cnt2 - 1)[::-1]:
                es[i] = e
                ies[i] = ie
                e *= e
                e %= MOD
                ie *= ie
                ie %= MOD
            now = 1
            for i in range(cnt2 - 2):
                self.sum_ie[i] = ies[i] * now % MOD
                now *= es[i]
                now %= MOD
        for ph in range(1, h + 1)[::-1]:
            w = 1 << (ph - 1)
            p = 1 << (h - ph)
            inow = 1
            for s in range(w):
                offset = s << (h - ph + 1)
                for i in range(p):
                    l = arr[i + offset]
                    r = arr[i + offset + p]
                    arr[i + offset] = (l + r) % MOD
                    arr[i + offset + p] = (MOD + l - r) * inow % MOD
                inow *= self.sum_ie[(~s & -~s).bit_length() - 1]
                inow %= MOD

    def convolution(self, a, b):
        n = len(a)
        m = len(b)
        if not n or not m: return []
        if min(n, m) <= 50:
            if n < m:
                n, m = m, n
                a, b = b, a
            res = [0] * (n + m - 1)
            for i in range(n):
                for j in range(m):
                    res[i + j] += a[i] * b[j]
                    res[i + j] %= MOD
            return res
        z = 1 << (n + m - 2).bit_length()
        a += [0] * (z - n)
        b += [0] * (z - m)
        self.butterfly(a)
        self.butterfly(b)
        for i in range(z):
            a[i] *= b[i]
            a[i] %= MOD
        self.butterfly_inv(a)
        a = a[:n + m - 1]
        iz = pow(z, MOD - 2, MOD)
        for i in range(n + m - 1):
            a[i] *= iz
            a[i] %= MOD
        return a

    def autocorrelation(self, a):
        n = len(a)
        if not n: return []
        if n <= 50:
            res = [0] * (2 * n - 1)
            for i in range(n):
                for j in range(n):
                    res[i + j] += a[i] * a[j]
                    res[i + j] %= MOD
            return res
        z = 1 << (2 * n - 2).bit_length()
        a += [0] * (z - n)
        self.butterfly(a)
        for i in range(a):
            a[i] *= a[i]
            a[i] %= MOD
        self.butterfly_inv(a)
        a = a[:2 * n - 1]
        iz = pow(z, MOD - 2, MOD)
        for i in range(2 * n - 1):
            a[i] *= iz
            a[i] %= MOD
        return a

import sys
input = sys.stdin.buffer.readline

N, M = map(int, input().split())
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

cv = Convolution_998244353()

print(*cv.convolution(A, B))

Buggy submission (verdict: Runtime Error):
MOD = 998244353
ROOT = 3

class Convolution_998244353():
    def __init__(self):
        self.first1 = True
        self.first2 = True
        self.sum_e = [0] * 30
        self.sum_ie = [0] * 30

    def inv_gcd(self, a, b):
        a %= b
        if a == 0: return b, 0
        s = b
        t = a
        m0 = 0
        m1 = 1
        while t:
            u = s // t
            s -= t * u
            m0 -= m1 * u
            s, t = t, s
            m0, m1 = m1, m0
        if m0 < 0: m0 += b // s
        return s, m0

    def butterfly(self, arr):
        n = len(arr)
        h = (n - 1).bit_length()
        if self.first1:
            self.first1 = False
            es = [0] * 30
            ies = [0] * 30
            m = MOD - 1
            cnt2 = (m & -m).bit_length() - 1
            e = pow(ROOT, m >> cnt2, MOD)
            ie = pow(e, MOD - 2, MOD)
            for i in range(cnt2 - 1)[::-1]:
                es[i] = e
                ies[i] = ie
                e *= e
                e %= MOD
                ie *= ie
                ie %= MOD
            now = 1
            for i in range(cnt2 - 2):
                self.sum_e[i] = es[i] * now % MOD
                now *= ies[i]
                now %= MOD
        for ph in range(1, h + 1):
            w = 1 << (ph - 1)
            p = 1 << (h - ph)
            now = 1
            for s in range(w):
                offset = s << (h - ph + 1)
                for i in range(p):
                    l = arr[i + offset]
                    r = arr[i + offset + p] * now
                    arr[i + offset] = (l + r) % MOD
                    arr[i + offset + p] = (l - r) % MOD
                now *= self.sum_e[(~s & -~s).bit_length() - 1]
                now %= MOD

    def butterfly_inv(self, arr):
        mod = self.mod
        g = self.root
        n = len(arr)
        h = (n - 1).bit_length()
        if self.first2:
            self.first2 = False
            es = [0] * 30
            ies = [0] * 30
            m = MOD - 1
            cnt2 = (m & -m).bit_length() - 1
            e = pow(ROOT, m >> cnt2, MOD)
            ie = pow(e, MOD - 2, MOD)
            for i in range(cnt2 - 1)[::-1]:
                es[i] = e
                ies[i] = ie
                e *= e
                e %= MOD
                ie *= ie
                ie %= MOD
            now = 1
            for i in range(cnt2 - 2):
                self.sum_ie[i] = ies[i] * now % MOD
                now *= es[i]
                now %= MOD
        for ph in range(1, h + 1)[::-1]:
            w = 1 << (ph - 1)
            p = 1 << (h - ph)
            inow = 1
            for s in range(w):
                offset = s << (h - ph + 1)
                for i in range(p):
                    l = arr[i + offset]
                    r = arr[i + offset + p]
                    arr[i + offset] = (l + r) % MOD
                    arr[i + offset + p] = (MOD + l - r) * inow % MOD
                inow *= self.sum_ie[(~s & -~s).bit_length() - 1]
                inow %= MOD

    def convolution(self, a, b):
        n = len(a)
        m = len(b)
        if not n or not m: return []
        if min(n, m) <= 50:
            if n < m:
                n, m = m, n
                a, b = b, a
            res = [0] * (n + m - 1)
            for i in range(n):
                for j in range(m):
                    res[i + j] += a[i] * b[j]
                    res[i + j] %= MOD
            return res
        z = 1 << (n + m - 2).bit_length()
        a += [0] * (z - n)
        b += [0] * (z - m)
        self.butterfly(a)
        self.butterfly(b)
        for i in range(z):
            a[i] *= b[i]
            a[i] %= MOD
        self.butterfly_inv(a)
        a = a[:n + m - 1]
        iz = pow(z, MOD - 2, MOD)
        for i in range(n + m - 1):
            a[i] *= iz
            a[i] %= MOD
        return a

    def autocorrelation(self, a):
        n = len(a)
        if not n: return []
        if n <= 50:
            res = [0] * (2 * n - 1)
            for i in range(n):
                for j in range(n):
                    res[i + j] += a[i] * a[j]
                    res[i + j] %= MOD
            return res
        z = 1 << (2 * n - 2).bit_length()
        a += [0] * (z - n)
        self.butterfly(a)
        for i in range(a):
            a[i] *= a[i]
            a[i] %= MOD
        self.butterfly_inv(a)
        a = a[:2 * n - 1]
        iz = pow(z, MOD - 2, MOD)
        for i in range(2 * n - 1):
            a[i] *= iz
            a[i] %= MOD
        return a

import sys
input = sys.stdin.buffer.readline

N, M = map(int, input().split())
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

cv = Convolution_998244353()

print(*cv.convolution(A, B))