提交记录 16103


用户 题目 状态 得分 用时 内存 语言 代码长度
ObsidianY 1002i. 【模板题】多项式乘法 Accepted 100 62.964 ms 8740 KB C++11 5.94 KB
提交时间 评测时间
2021-03-25 22:21:19 2021-03-25 22:21:25
// author: ycp | https://ycpedef.github.io
// #pragma GCC diagnostic error "-std=c++11"
// #pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdarg>
#include <cmath>
#define debug(x) cerr << #x << " = " << x << endl
#define debugf(...) fprintf(stderr, __VA_ARGS__)
#define wlog(fmt, ...) fprintf(stderr, "<%s:%d> " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
using namespace std;
template<class T> bool cmax(T &a, T b) { return b > a ? (a = b, 1) : 0; }
template<class T> bool cmin(T &a, T b) { return b < a ? (a = b, 1) : 0; }
template<class T> void read(T &a) {
    a = 0; char c = getchar(); int f = 0;
    while (!isdigit(c)) { f ^= c == '-',  c = getchar(); }
    while (isdigit(c)) { a = a * 10 + (c ^ 48),  c = getchar(); }
    a *= f ? -1 : 1;
}
struct Fastin {
    template<class T> Fastin& operator >> (T &x) { read(x); return *this; }
} fastin;

#include <utility>
#include <cstring>
#include <cstdio>
#include <cctype>

namespace poly {

using u64 = unsigned long long;
using std::forward;

const u64 mod = 998244353;
const u64 G = 3;

u64 *log2 = nullptr, rev_limit = 1;
int *rev = nullptr;

inline u64 power(u64 a, int b);
inline void swap(u64 &a, u64 &b);
inline void reverse(u64* p1, u64* p2);
inline void read(u64 &a);
inline void init(int n);

struct poly_t {
    u64 *src; int deg;

    inline void read(int);
    inline void print(int) const;

    poly_t(int); poly_t(int, int);
    poly_t(const poly_t &); poly_t(poly_t &&);
    ~poly_t() { delete[] src; }
    void resize(int);
    void copy(const poly_t &);
    poly_t& operator = (const poly_t &);
    poly_t& operator = (poly_t &&);
    u64& operator [] (const int &x) { return src[x]; }
    u64 operator [] (const int &x) const { return src[x]; }

    inline void   NTT(int);
    inline void   DFT() { return NTT(1); }
    inline void   IDFT() { return NTT(-1); }
    inline poly_t inv() const;
    inline poly_t ln() const;
    inline poly_t exp() const;
};

// -------------------------- poly_t start ----------------------------

#define cp(dest, src, cnt) memcpy(dest, src, cnt * sizeof(u64))
inline void poly_t::copy(const poly_t &p) {
    wlog("copy");
    deg = p.deg; src = new u64[deg](); cp(src, p.src, deg);
}
void poly_t::resize(int c) {
    if (c <= deg) return;
    u64 *pre = src; src = new u64[c](); cp(src, pre, deg);
    deg = c, delete[] pre;
}
#undef cp

poly_t::poly_t(int siz) {wlog("new"); deg = siz; src = new u64[deg](); }
poly_t::poly_t(int siz, int n) { deg = siz; src = new u64[deg](); read(n); }
poly_t::poly_t(const poly_t& p) { copy(p); }
poly_t::poly_t(poly_t &&p) { wlog("move");deg = p.deg, src = p.src, p.src = nullptr; }
poly_t& poly_t::operator = (const poly_t& p) {
    if (this != &p) { delete[] src; copy(p); }
    return *this;
}
poly_t& poly_t::operator = (poly_t &&p) {
    if (this != &p) {
        delete[] src; deg = p.deg, src = p.src, p.src = nullptr;
    }
    return *this;
}

inline void poly_t::read(int n) {
    for (int i = 0; i < n; i++) { poly::read(src[i]); }
}
inline void poly_t::print(int n) const {
    for (int i = 0; i < n; i++) { printf("%llu ", src[i]); } putchar('\n');
}

inline void poly_t::NTT(int mode) {
    for (int i = 0; i < deg; i++) {
        if (i < rev[i]) swap(src[i], src[rev[i]]);
    }

    u64 *f = src;
    for (int len = 2, k = 1, i, j; len <= deg; len <<= 1, k <<= 1) {
        u64 g0 = power(G, (mod - 1) / len);
        for (i = 0; i != deg; i += len) {
            u64 g = 1, t1, t2;
            for (j = i; j < i + k; j++) {
                t1 = f[j], t2 = (g * f[j + k]) % mod;
                f[j] = t1 + t2;
                f[j + k] = t1 - t2 + mod;
                (g *= g0) %= mod;
            }
        }
        if ((len >> 17) & 1) {
            for (int i = 0; i < deg; i++) { f[i] %= mod; }
        }
    }

    if (mode < 0) {
        poly::reverse(f + 1, f + deg);
        u64 inv = power(deg, mod - 2);
        for (int i = 0; i < deg; i++) f[i] *= inv;
    }
    for (int i = 0; i < deg; i++) f[i] %= mod;
}

inline poly_t poly_t::inv() const {
    poly_t f(*this);
    //TODO
    return f;
}

inline poly_t poly_t::ln() const {
    poly_t f(*this);
    //TODO
    return f;
}

inline poly_t poly_t::exp() const {
    poly_t f(*this);
    //TODO
    return f;
}

poly_t inv(const poly_t &p) { return p.inv(); }
poly_t ln(const poly_t &p) { return p.ln(); }
poly_t exp(const poly_t &p) { return p.exp(); }

template<typename T>
poly_t operator * (T p1, T p2) {
    poly_t a(forward<T>(p1)), b(forward<T>(p2));
    a.DFT(), b.DFT();
    poly_t c(a.deg);
    for (int i = 0; i < c.deg; i++) (c[i] = a[i] * b[i]) %= mod;
    c.IDFT();
    return c;
}

//------------------------- poly_t end -------------------------------

inline u64 power(u64 a, int b) {
    u64 res = 1;
    while (b) { if (b & 1) (res *= a) %= mod; b >>= 1, (a *= a) %= mod; }
    return res;
}
inline void swap(u64 &a, u64 &b) { u64 t = a; a = b, b = t; }

inline void reverse(u64* p1, u64* p2) { p2--; while (p1 < p2) { swap(*p1, *p2), p1++, p2--; } }

inline void read(u64 &a) {
    a = 0; char c = getchar(); int f = 0;
    while (!isdigit(c)) { f ^= c == '-',  c = getchar(); }
    while (isdigit(c)) { a = a * 10 + (c ^ 48),  c = getchar(); }
    a *= f ? -1 : 1;
}

inline void print(u64 a) {
    if (!a) return;
    print(a / 10);
    putchar(a % 10 + '0');
}

inline void init(int n = 1e6) {
    //delete[] poly::log2, poly::log2 = new u64[n + 10]();
    //poly::log2[0] = -1;
    //for (int i = 1; i <= n; i++) {
    //    poly::log2[i] = poly::log2[i >> 1] + 1;
    //}
    delete[] rev, rev = new int[n + 10]();
    while ((rev_limit << 1) <= n) rev_limit <<= 1;
    for (int i = 0; i < rev_limit; i++) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (n >> 1));
    }
}

} // namespace poly

using poly::poly_t;

int n, m;

int main() {
    fastin >> n >> m;
    int len = 1 << ((unsigned)log2(n + m + 1) + 1);
    poly::init(len);
    poly_t a(len, n + 1);
    poly_t b(len, m + 1);
    (std::move(a) * std::move(b)).print(n + m + 1);
    return 0;
}


CompilationN/AN/ACompile OKScore: N/A

Subtask #1 Testcase #139.66 us40 KBAcceptedScore: 0

Subtask #1 Testcase #262.746 ms8 MB + 468 KBAcceptedScore: 0

Subtask #1 Testcase #329.047 ms3 MB + 832 KBAcceptedScore: 100

Subtask #1 Testcase #429.215 ms3 MB + 820 KBAcceptedScore: 0

Subtask #1 Testcase #542.38 us40 KBAcceptedScore: 0

Subtask #1 Testcase #640.29 us40 KBAcceptedScore: 0

Subtask #1 Testcase #742.02 us40 KBAcceptedScore: 0

Subtask #1 Testcase #857.301 ms8 MB + 200 KBAcceptedScore: 0

Subtask #1 Testcase #957.205 ms8 MB + 200 KBAcceptedScore: 0

Subtask #1 Testcase #1051.837 ms7 MB + 956 KBAcceptedScore: 0

Subtask #1 Testcase #1162.964 ms8 MB + 548 KBAcceptedScore: 0

Subtask #1 Testcase #1262.766 ms7 MB + 428 KBAcceptedScore: 0

Subtask #1 Testcase #1339.59 us40 KBAcceptedScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2026-03-19 18:53:12 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠