ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多项式板子

2022-01-14 21:32:44  阅读:156  来源: 互联网

标签:sz const int 多项式 poly 板子 mul mod


丢个好看一点的\(poly\)板子

多项式求逆

在这里插入图片描述

ln

在这里插入图片描述

exp

在这里插入图片描述

#include<bits/stdc++.h>
#define N 800050
#define sz(x) ((int)x.size())
#define poly vector<int>
#define mod 998244353
using namespace std;
int add(int x, int y) { x += y;
    if(x >= mod) x -= mod;
    return x;
}
int sub(int x, int y) { x -= y;
    if(x < 0) x += mod;
    return x;
}
int mul(int x, int y) {
    return 1ll * x * y % mod;
}
int qpow(int x, int y) {
    int ret = 1;
    for(; y; y >>= 1, x = mul(x, x)) if(y & 1) ret = mul(ret, x);
    return ret;
}
const int G = 3;
const int Ginv = qpow(G, mod - 2);
int rev[N << 1];
void ntt(int *a, int n, int o) {
    for(int i = 0; i < n; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (n >> 1));
    for(int i = 0; i < n; i ++) if(rev[i] > i) swap(a[i], a[rev[i]]);
    for(int len = 2; len <= n; len <<= 1) {
        int w0 = qpow((o == 1)? G : Ginv, (mod - 1) / len);
        for(int j = 0; j < n; j += len) {
            int wn = 1;
            for(int k = j; k < j + (len >> 1); k ++, wn = mul(wn, w0)) {
                int X = a[k], Y = mul(a[k + (len >> 1)], wn);
                a[k] = add(X, Y), a[k + (len >> 1)] = sub(X, Y);
            }   
        }
    }
    int ninv = qpow(n, mod - 2);
    if(o == -1)
        for(int i = 0; i < n; i ++) a[i] = mul(a[i], ninv);
}
poly operator + (const poly &A, const poly & B) {
    poly C = A; C.resize(max(sz(A), sz(B)));
    for(int i = 0; i < sz(B); i ++) C[i] = add(C[i], B[i]);
    return C;
}
poly operator - (const poly &A, const poly & B) {
    poly C = A; C.resize(max(sz(A), sz(B)));
    for(int i = 0; i < sz(B); i ++) C[i] = sub(C[i], B[i]);
    return C;
}
#define clr(a, n) (memset(a, 0, sizeof(int) * n))
int a[N << 1], b[N << 1], lim;
poly operator * (const poly & A, const poly & B) {
    for(int i = 0; i < sz(A); i ++) a[i] = A[i];
    for(int i = 0; i < sz(B); i ++) b[i] = B[i];
    poly C; C.resize(min(lim, sz(A) + sz(B) - 1));
    int len = 1;
    for(; len <= sz(A) + sz(B) - 1; len <<= 1);
    ntt(a, len, 1), ntt(b, len, 1);
    for(int i = 0; i < len; i ++) a[i] = mul(a[i], b[i]);
    ntt(a, len, -1);
    for(int i = 0; i < sz(C); i ++) C[i] = a[i];
    clr(a, len), clr(b, len);
    return C;
}
poly operator * (const int & a, const poly & A) {
    poly C; C.resize(sz(A));
    for(int i = 0; i < sz(A); i ++) C[i] = mul(A[i], a);
    return C;
}
void pINV(poly &A, poly &B, int n) {
    if(n == 1) B.push_back(qpow(A[0], mod - 2));
    else {
        pINV(A, B, (n + 1) / 2);
        poly C = A; C.resize(n);
        B = 2 * B - B * B * C;
        B.resize(n);
    }
    
}
poly INV(poly A) {
    poly B; pINV(A, B, sz(A));
    return B;
}
int inv[N];
void init(int n) {
    inv[1] = 1;
    for(int i = 2; i <= n; i ++)
        inv[i] = sub(0, mul(mod / i, inv[mod % i]));
}
poly qiudao(const poly A) {
    poly B;
    for(int i = 1; i < sz(A); i ++) B.push_back(mul(i, A[i]));
    return B;
}
poly jifen(const poly A) {
    poly B; B.resize(sz(A));
    for(int i = 1; i < sz(A); i ++) B[i] = mul(A[i - 1], inv[i]);
    B[0] = 0;
    return B;
}
poly ln(const poly A) {
    return jifen(qiudao(A) * INV(A));
}
void pexp(poly &A, poly & B, int n) {
    if(n == 1) B.push_back(1);
    else {
        pexp(A, B, (n + 1) / 2);
        poly lnB; lnB = B; lnB.resize(n);
        lnB = ln(lnB);
        for(int i = 0; i < sz(lnB); i ++) lnB[i] = sub(A[i], lnB[i]);
        lnB[0] = add(lnB[0], 1);
        B = B * lnB;
        B.resize(n);
    }
}
poly exp(poly A) {
    poly C; pexp(A, C, sz(A));
    return C;
}
poly f;
int n;
int main() {
    scanf("%d", &n); lim = n; init(n);
    f.resize(n);
    for(int i = 0; i < n; i ++) scanf("%d", &f[i]);
    f = exp(f);
    for(int i = 0; i < n; i ++) printf("%d ", f[i]);
    return 0;
}

标签:sz,const,int,多项式,poly,板子,mul,mod
来源: https://www.cnblogs.com/lahlah/p/15805063.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有