QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#848964#9945. Circular ConvolutionToboWA 347ms84016kbC++204.3kb2025-01-09 11:01:052025-01-09 11:01:05

Judging History

This is the latest submission verdict.

  • [2025-01-09 11:01:05]
  • Judged
  • Verdict: WA
  • Time: 347ms
  • Memory: 84016kb
  • [2025-01-09 11:01:05]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;
// using i64 = long long;
// using i128 = __int128_t;

bool Memory_begin;

#define int long long
#define i64 __int128_t
const int N = 2e5 + 5, P = 4179340454199820289;
// using i64 = long long;
using Poly = vector<int>;
/*---------------------------------------------------------------------------*/
#define MUL(a, b) (i64(a) * (b))
#define ADD(a, b) ((a) += (b)) // (a += b) %= P
#define SUB(a, b) ((a) -= (b)) // ((a -= b) += P) %= P
Poly getInv(int L)
{
    Poly inv(L);
    inv[1] = 1;
    for (int i = 2; i < L; i++)
        inv[i] = MUL((P - P / i), inv[P % i]);
    return inv;
}
int POW(i64 a, int b = P - 2, i64 x = 1)
{
    for (; b; b >>= 1, a = a * a % P)
        if (b & 1)
            x = x * a % P;
    return x;
}
namespace NTT
{
    const int g = 3;
    Poly Omega(int L)
    {
        int wn = POW(g, P / L);
        Poly w(L);
        w[L >> 1] = 1;
        for (int i = L / 2 + 1; i < L; i++)
            w[i] = MUL(w[i - 1], wn);
        for (int i = L / 2 - 1; i >= 1; i--)
            w[i] = w[i << 1];
        return w;
    }
    auto W = Omega(1 << 21); // Length
    void DIF(int *a, int n)
    {
        for (int k = n >> 1; k; k >>= 1)
            for (int i = 0, y; i < n; i += k << 1)
                for (int j = 0; j < k; ++j)
                    y = a[i + j + k], a[i + j + k] = MUL(a[i + j] - y, W[k + j]), ADD(a[i + j], y);
    }
    void IDIT(int *a, int n)
    {
        for (int k = 1; k < n; k <<= 1)
            for (int i = 0, x, y; i < n; i += k << 1)
                for (int j = 0; j < k; ++j)
                    x = a[i + j], y = MUL(a[i + j + k], W[k + j]),
                    a[i + j + k] = x - y, ADD(a[i + j], y);
        int Inv = P - (P - 1) / n;
        for (int i = 0; i < n; i++)
            a[i] = MUL(a[i], Inv);
        reverse(a + 1, a + n);
    }
}
/*---------------------------------------------------------------------------*/
namespace Polynomial
{
    // basic operator
    int norm(int n) { return 1 << (__lg(n - 1) + 1); }
    void norm(Poly &a)
    {
        if (!a.empty())
            a.resize(norm(a.size()), 0);
        else
            a = {0};
    }
    void DFT(Poly &a) { NTT::DIF(a.data(), a.size()); }
    void IDFT(Poly &a) { NTT::IDIT(a.data(), a.size()); }
    Poly &dot(Poly &a, Poly &b)
    {
        for (int i = 0; i < a.size(); i++)
            a[i] = MUL(a[i], b[i]);
        return a;
    }

    // mul / div int
    Poly &operator*=(Poly &a, int b)
    {
        for (auto &x : a)
            x = MUL(x, b);
        return a;
    }
    Poly operator*(Poly a, int b) { return a *= b; }
    Poly operator*(int a, Poly b) { return b * a; }
    Poly &operator/=(Poly &a, int b) { return a *= POW(b); }
    Poly operator/(Poly a, int b) { return a /= b; }

    // Poly add / sub
    Poly &operator+=(Poly &a, Poly b)
    {
        a.resize(max(a.size(), b.size()));
        for (int i = 0; i < b.size(); i++)
            ADD(a[i], b[i]);
        return a;
    }
    Poly operator+(Poly a, Poly b) { return a += b; }
    Poly &operator-=(Poly &a, Poly b)
    {
        a.resize(max(a.size(), b.size()));
        for (int i = 0; i < b.size(); i++)
            SUB(a[i], b[i]);
        return a;
    }
    Poly operator-(Poly a, Poly b) { return a -= b; }

    // Poly mul
    Poly operator*(Poly a, Poly b)
    {
        int n = a.size() + b.size() - 1, L = norm(n);
        if (a.size() <= 8 || b.size() <= 8)
        {
            Poly c(n);
            for (int i = 0; i < a.size(); i++)
                for (int j = 0; j < b.size(); j++)
                    c[i + j] += a[i] * b[j];
            return c;
        }
        a.resize(L), b.resize(L);
        DFT(a), DFT(b), dot(a, b), IDFT(a);
        return a.resize(n), a;
    }
}
using namespace Polynomial;

bool Memory_end;

signed main()
{
    cin.tie(nullptr)->sync_with_stdio(false);

    cerr << (&Memory_end - &Memory_begin) / 1048576.0 << "MB" << '\n';

    int n;
    cin >> n;
    Poly a(n), b(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < n; i++)
        cin >> b[i];
    auto c = a * b;
    for (int i = n; i < c.size(); i++)
        c[i - n] = (c[i - n] + c[i]);
    for (int i = 0; i < n; i++)
        cout << c[i] << ' ';
}
/*

 */

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 19572kb

input:

3
1 1 4
5 1 4

output:

13 22 25 

result:

ok 3 number(s): "13 22 25"

Test #2:

score: 0
Accepted
time: 10ms
memory: 19492kb

input:

3
1 2 3
-1 2 0

output:

5 0 1 

result:

ok 3 number(s): "5 0 1"

Test #3:

score: 0
Accepted
time: 4ms
memory: 19296kb

input:

3
1 2 4
-1 1 0

output:

3 -1 -2 

result:

ok 3 number(s): "3 -1 -2"

Test #4:

score: 0
Accepted
time: 0ms
memory: 19564kb

input:

1
1000000
1000000

output:

1000000000000 

result:

ok 1 number(s): "1000000000000"

Test #5:

score: 0
Accepted
time: 271ms
memory: 84000kb

input:

1000000
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

result:

ok 1000000 numbers

Test #6:

score: -100
Wrong Answer
time: 347ms
memory: 84016kb

input:

1000000
-881218 -558526 -910874 -6842 -969355 -727356 -908202 -230188 -861493 -755231 -547147 -361322 -259909 -134366 -104312 -683109 -972495 -784717 -75027 -899836 -645370 -386525 -440026 -13261 -402678 -624676 -970518 -84749 -454793 -199069 -973352 -771037 -314793 -987539 -422981 -953310 -199002 -...

output:

-8677373586167562240 4764342055340081152 6016091259049869312 -812337888288047104 4172572371082805248 -7745835528368422912 2554902166078750720 8062402090305060864 -8997131563921571840 3290226678256631808 -6149897661890691072 2932572926131568640 5467778410577133568 564861359695593472 26829196240596500...

result:

wrong answer 1st numbers differ - expected: '249834516261376798', found: '-8677373586167562240'