QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#848967#9945. Circular ConvolutionCappsWA 1062ms174116kbC++207.6kb2025-01-09 11:01:292025-01-09 11:01:31

Judging History

This is the latest submission verdict.

  • [2025-01-09 11:01:31]
  • Judged
  • Verdict: WA
  • Time: 1062ms
  • Memory: 174116kb
  • [2025-01-09 11:01:29]
  • Submitted

answer

#include <bits/stdc++.h>

using i64 = long long;

template <class T>
class FloatPointNumber {
    static constexpr T EPS = 1E-12;
    static_assert(EPS >= 0, "EPS < 0");

    static constexpr int sgn(T x) {
        return x < -EPS ? -1 : x > EPS;
    }

    static int precision;
    static std::string inputStr;

    T x;
public:
    constexpr FloatPointNumber() : x{} {}
    constexpr FloatPointNumber(T x) : x{x} {}

    constexpr T val() const {
        return x;
    }

    constexpr int sgn() const {
        return sgn(x);
    }

    template <class G>
    constexpr G round() const {
        if (x >= 0) {
            return G(x + 0.5 + EPS);
        } else {
            return G(x - 0.5 - EPS);
        }
    }

    static constexpr void setprecision(int len) {
        precision = len;
    }

    // 四则运算

    FloatPointNumber &operator+=(FloatPointNumber a) & {
        x += a.x;
        return *this;
    }

    friend constexpr FloatPointNumber operator+(FloatPointNumber a, FloatPointNumber b) {
        return a += b;
    }

    constexpr FloatPointNumber operator-() const {
        return FloatPointNumber(-x);
    }

    FloatPointNumber &operator-=(FloatPointNumber a) & {
        x = x - a.x;
        return *this;
    }

    friend constexpr FloatPointNumber operator-(FloatPointNumber a, FloatPointNumber b) {
        return a -= b;
    }

    FloatPointNumber &operator*=(FloatPointNumber a) & {
        x *= a.x;
        return *this;
    }

    friend constexpr FloatPointNumber operator*(FloatPointNumber a, FloatPointNumber b) {
        return a *= b;
    }

    constexpr FloatPointNumber &operator/=(FloatPointNumber a) & {
        x /= (long double)a.x;
        return *this;
    }

    friend constexpr FloatPointNumber operator/(FloatPointNumber a, FloatPointNumber b) {
        return a /= b;
    }

    // 比较运算

    friend constexpr int operator<(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) < 0;
    }

    friend constexpr int operator<=(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) <= 0;
    }

    friend constexpr int operator>(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) > 0;
    }

    friend constexpr int operator>=(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) >= 0;
    }

    friend constexpr bool operator==(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) == 0;
    }

    friend constexpr bool operator!=(FloatPointNumber a, FloatPointNumber b) {
        return sgn(a.x - b.x) != 0;
    }

    // 输入输出

    friend constexpr std::istream &operator>>(std::istream &is, FloatPointNumber &a) {
        is >> inputStr;
        if (std::is_same<T, long double>::value) {
            a = FloatPointNumber(std::stold(inputStr));
        } else {
            a = FloatPointNumber(std::stod(inputStr));
        }
        return is;
    }

    friend constexpr std::ostream &operator<<(std::ostream &os, FloatPointNumber a) {
        return os << std::fixed << std::setprecision(precision) << a.val();
    }

    // 常数
    static constexpr FloatPointNumber PI = FloatPointNumber(acosl(-1));
};

template <class T>
std::string FloatPointNumber<T>::inputStr;

template <class T>
constexpr FloatPointNumber<T> std::abs(FloatPointNumber<T> x) {
    if (x.val() < 0) {
        x = -x;
    }
    return x;
}

template <class T>
constexpr FloatPointNumber<T> std::atan2(FloatPointNumber<T> x, FloatPointNumber<T> y) {
    return std::atan2(1.L * x.val(), 1.L * y.val());
}

template <class T>
constexpr FloatPointNumber<T> std::sin(FloatPointNumber<T> x) {
    return std::sin(1.L * x.val());
}

template <class T>
constexpr FloatPointNumber<T> std::cos(FloatPointNumber<T> x) {
    return std::cos(1.L * x.val());
}

template <class T>
constexpr FloatPointNumber<T> std::sqrt(FloatPointNumber<T> x) {
    return std::sqrt(1.L * x.val());
}

template <class T>
int FloatPointNumber<T>::precision = 6;

using Float = FloatPointNumber<double>;

template <class T, template <class G> class Complex>
class Polynomial : public std::vector<T> {
    using Comp = Complex<T>;

    static std::vector<Comp> w[2];
    static std::vector<int> r;

    static void init(int _log) {
        if (r.size() == (1 << _log)) {
            return;
        }

        int n = 1 << _log;
        r.assign(n, 0);
        for (int i = 1; i < n; i++) {
            r[i] = (r[i >> 1] >> 1) | ((i & 1) << (_log - 1));
        }

        w[0].assign(n, Comp());
        w[1].assign(n, Comp());

        const T PI = acosl(-1);
        for (int i = 0; i < n; i++) {
            auto th = PI * i / n;
            auto cth = std::cos(1.L * th);
            auto sth = std::sin(1.L * th);
            w[0][i] = Comp(cth, sth);
            w[1][i] = Comp(cth, -sth);
        }
    }

    static void fft(std::vector<Comp> &a, int op) {
        int n = a.size();
        init(std::__lg(n));
        for (int i = 0; i < n; i++) {
            if (i < r[i]) {
                std::swap(a[i], a[r[i]]);
            }
        }
        for (int mid = 1; mid < n; mid <<= 1) {
            const int d = n / mid;
            for (int R = mid << 1, j = 0; j < n; j += R) {
                for (int k = 0; k < mid; k++) {
                    Comp x = a[j + k];
                    Comp y = w[op][d * k] * a[j + mid + k];
                    a[j + k] = x + y;
                    a[j + mid + k] = x - y;
                }
            }
        }
    }

public:
    using std::vector<T>::vector;

    constexpr friend Polynomial operator*(const Polynomial &a, const Polynomial &b) {
        if (a.size() == 0 or b.size() == 0) {
            return Polynomial();
        }
        int n = a.size() + b.size() - 1;
        int _log = std::__lg(2 * n - 1);
        int s = 1 << _log;
        if (std::min(a.size(), b.size()) < 128) {
            Polynomial res(n);
            for (int i = 0; i < a.size(); i++) {
                for (int j = 0; j < b.size(); j++) {
                    res[i + j] += a[i] * b[j];
                }
            }
            return res;
        }

        std::vector<Comp> p(s), q(s);
        for (int i = 0; i < a.size(); i++) {
            p[i] = Comp(a[i], 0);
        }
        for (int i = 0; i < b.size(); i++) {
            q[i] = Comp(b[i], 0);
        }

        fft(p, 0);
        fft(q, 0);
        for (int i = 0; i < s; i++) {
            p[i] = p[i] * q[i];
        }
        fft(p, 1);

        Polynomial res(n);
        for (int i = 0; i < n; i++) {
            res[i] = p[i].real() / s; // 默认浮点数
        }
        return res;
    }
};

template <class T, template <class G> class Complex>
std::vector<Complex<T>> Polynomial<T, Complex>::w[2] = {};

template <class T, template <class G> class Complex>
std::vector<int> Polynomial<T, Complex>::r;

using Poly = Polynomial<Float, std::complex>;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int n;
    std::cin >> n;

    Poly p(n), q(n);
    for (int i = 0; i < n; i++) {
        int x;
        std::cin >> x;
        p[i] = x;
    }
    
    for (int i = 0; i < n; i++) {
        int x;
        std::cin >> x;
        q[i] = x;
    }

    p = p * q;
    
    for (int i = n; i < p.size(); i++) {
        p[i - n] += p[i];
    }
    p.resize(n);

    for (int i = 0; i < n; i++) {
        std::cout << p[i].round<i64>() << " \n"[i + 1 == n];
    }

    return 0;
}



詳細信息

Test #1:

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

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: 0ms
memory: 3592kb

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: 0ms
memory: 3552kb

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: 3680kb

input:

1
1000000
1000000

output:

1000000000000

result:

ok 1 number(s): "1000000000000"

Test #5:

score: 0
Accepted
time: 1004ms
memory: 174028kb

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: 1062ms
memory: 174116kb

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:

249834516261376832 250033244986869824 250018516809656480 250043162241643008 250047307005230848 249960143714092800 249955852221357248 250026384381548704 250026566302278944 250107844830331072 250033211167036608 249949178512153664 249898401524703680 249953245638099712 250023894911609728 250055432589110...

result:

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