ICode9

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

LuoGuP4721:【模板】分治 FFT

2019-08-14 12:50:59  阅读:231  来源: 互联网

标签:LuoGuP4721 int FFT rev tot base inline 模板 mod


Pre

式子变换需要注意一下

Solution

注意到\(f(x)g(x)+f_0=f(x)\)

其实开始我没看出来,后来发现仔细分析一下就可以了。

然后式子变换

\(f(x)=\frac{f_0}{1-g(x)}\)

注意这里的\(1-\)是只减常数项,因为这里的\(f(x)\)和\(g(x)\)是指的函数,而不是系数。

Code

#include <cstdio>
#include <queue>
#include <cstring>
#define ll long long
#define xx first
#define yy second
using namespace std;
inline void swap (int &a, int &b) {
    int c = a;
    a = b,
    b = c;
}
const int N = 250000 + 5, mod = 998244353, inver = 332748118;
int nn, g[N], f[N];
inline int add (int u, int v) {return u + v >= mod ? u + v - mod : u + v;}
inline int mns (int u, int v) {return u - v < 0 ? u - v + mod : u - v;}
inline int mul (int u, int v) {return 1LL * u * v % mod;}
inline int qpow (int u, int v) {
    int tot = 1, base = u % mod;
    while (v){
        if (v & 1) tot = mul (tot, base);
        base = mul (base, base);
        v >>= 1;
    }
    return tot;
}
int c[N], rev[N];
inline void NTT (int *a, int n, int bit, bool flag) {
    for (int i = 0; i < n; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
        if (i > rev[i]) swap (a[i], a[rev[i]]);
    }
    for (int l = 2; l <= n; l <<= 1) {
        int wi = qpow (flag ? inver : 3, (mod - 1) / l);
        int m = l / 2;
        for (int *k = a; k != a + n; k += l) {
            int w = 1;
            for (int i = 0; i < m; ++i) {
                int tmp = mul (k[i + m], w);
                k[i + m] = mns (k[i], tmp);
                k[i] = add (k[i], tmp);
                w = mul (w, wi);
            }
        }
    }
    int tmp = qpow (n, mod - 2);
    for (int i = 0; i < n && flag; ++i) {
        a[i] = mul (a[i], tmp);
    }
}
inline void Inv (int *a, int *b, int deg) {
    if (deg == 1) {
        b[0] = qpow (a[0], mod - 2);
        return ;
    }
    Inv (a, b, (deg + 1) >> 1);
    int n = 1, bit = 0;
    while (n < (deg << 1)) n <<= 1, ++bit;
    for (int i = 0; i < deg; ++i) c[i] = a[i]; for (int i = deg; i < n; ++i) c[i] = 0;
    NTT (c, n, bit, false);
    NTT (b, n, bit, false);
    for (int i = 0; i < n; ++i) b[i] = mns (mul (2, b[i]), mul (c[i], mul (b[i], b[i])));
    NTT (b, n, bit, true);
    for (int i = deg; i < n; ++i) b[i] = 0;
}
int main () {
    #ifdef chitongz
    freopen ("x.in", "r", stdin);
    #endif
    scanf ("%d", &nn);
    for (int i = 1; i <= nn - 1; ++i) scanf ("%d", &g[i]), g[i] = mns (mod, g[i]);
    g[0] = add (g[0], 1);
    Inv (g, f, nn);
    for (int i = 0; i < nn; ++i) printf ("%d ", f[i]);
    puts ("");
    return 0;
}

Conclusion

注意一下什么时候系数减法,什么时候常熟减法。

标签:LuoGuP4721,int,FFT,rev,tot,base,inline,模板,mod
来源: https://www.cnblogs.com/ChiTongZ/p/11351252.html

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

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

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

ICode9版权所有