Polynomial Notes

咕咕咕

\(\text{Inv}\)

\[\because FG\equiv1(\bmod\ x^n) \]

\[\therefore FG\equiv1(\bmod\ x^{\frac{n}{2}}) \]

\[FG_0\equiv1(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore F(G-G_0)\equiv0(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore G-G_0\equiv 0(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore (G-G_0)^2\equiv 0(\bmod \ x^n) \]

\[\therefore G^2-2GG_0+G_0^2\equiv 0(\bmod\ x^n) \]

\[\therefore F(G^2-2GG_0+G_0^2)\equiv 0(\bmod\ x^n) \]

\[\therefore G-2G_0+FG_0^2\equiv0(\bmod\ x^n) \]

\[\therefore G\equiv2G_0-FG_0^2(\bmod\ x^n) \]

\(T(n) = T(\frac{n}{2})+O(n\log n)=O(n\log n)\)


\(\text{Sqrt}\)

\[\because F\equiv G^2(\bmod\ x^n) \]

\[\therefore F\equiv G^2(\bmod\ x^{\frac{n}{2}}) \]

\[F\equiv G_0^2(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore F(G^2-G_0^2)\equiv0(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore G^2-G_0^2\equiv0(\bmod\ x^{\frac{n}{2}}) \]

\[\therefore (G^2-G_0^2)^2\equiv0(\bmod\ x^n) \]

\[\therefore G^4-2G^2G_0^2+G_0^4\equiv0(\bmod\ x^n) \]

\[\therefore G^4+2G^2G_0^2+G_0^4\equiv 4G^2G_0^2(\bmod\ x^n) \]

\[\therefore (G^2+G_0^2)^2\equiv 4G^2G_0^2(\bmod\ x^n) \]

\[\therefore G^2+G_0^2\equiv 2GG_0(\bmod\ x^n) \]

\[\therefore F+G_0^2\equiv 2GG_0(\bmod\ x^n) \]

\[\therefore G\equiv\dfrac{F+G_0^2}{2G_0}(\bmod x^n) \]

求逆即可。

\(T(n)=T(\frac{n}{2})+O(n\log n)=O(n\log n)\)


\(\ln\)

\[G\equiv \ln(F)(\bmod\ x^n) \]

\[f(x)=\text{ln}(x) \]

\[G\equiv f(F)(\bmod\ x^n) \]

\[\therefore G'\equiv f'(F)F'(\bmod\ x^n) \]

\(\text{ln}(x)=\frac{1}{x}\)

\[G'\equiv \dfrac{F'}{F}(\bmod\ x^n) \]

\[\therefore \int G'\equiv\int\dfrac{F'}{F}(\bmod\ x^n) \]

\[\therefore G\equiv\int\dfrac{F'}{F}(\bmod\ x^n) \]

求逆即可。

//n 表示项数
const int N = 2.7e5 + 10;
namespace Polynomial {
    const int mod = 998244353, G = 3, Gi = 332748118, inv2 = 499122177, img = 86583718;
    int lim, rev[N], a[N], b[N], c[N];
    int qpow(int a, int k) {
        int res = 1;
        for(; k; a = 1ll * a * a % mod, k >>= 1)
            if(k & 1) res = 1ll * res * a % mod;
        return res;
    }
    void NTT(int *f, int T) {
        for(int i = 0; i < lim; i++)
            if(i < rev[i]) 
                swap(f[i], f[rev[i]]);
        for(int mid = 1; mid < lim; mid <<= 1) {
            int wn = qpow(T == 1 ? G : Gi, (mod - 1) / (mid << 1));
            int len = mid << 1;
            for(int i = 0; i < lim; i += mid << 1) {
                int w = 1;
                for(int j = 0; j < mid; j++, w = 1ll * w * wn % mod) {
                    int x = f[i + j], y = 1ll * w * f[i + j + mid] % mod;
                    f[i + j] = (x + y) % mod;
                    f[i + j + mid] = (x - y + mod) % mod;
                }
            }
        }
        if(T == -1) {
            int inv = qpow(lim, mod - 2);
            for(int i = 0; i < lim; i++) 
                f[i] = 1ll * f[i] * inv % mod;
        }
    }
    void init(int n) {
        for(lim = 1; lim < n; lim <<= 1);
        for(int i = 0; i < lim; i++)
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (lim >> 1));
    } 
    void mul(int *f, int *g, int *h, int n, int m) {
        static int a[N], b[N];
        init(n + m - 1);
        memset(a, 0, lim << 2);
        memcpy(a, f, n << 2);
        memset(b, 0, lim << 2);
        memcpy(b, g, m << 2);
        NTT(a, 1), NTT(b, 1);
        for(int i = 0; i < lim; i++) 
            h[i] = 1ll * a[i] * b[i] % mod;
        NTT(h, -1);
    }
    void inv(int *f, int *g, int n) {
        if(n == 1) { g[0] = qpow(f[0], mod - 2); return; }
        inv(f, g, n + 1 >> 1);
        init(n << 1);
        copy(f, f + n, a);
        fill(a + n, a + lim, 0);
        NTT(a, 1), NTT(g, 1);
        for(int i = 0; i < lim; i++)
            g[i] = (2 - 1ll * a[i] * g[i] % mod + mod) % mod * g[i] % mod;
        NTT(g, -1);
        fill(g + n, g + lim, 0);
    }
    void div(int *f, int *g, int *q, int *r, int n, int m) {
        static int a[N], b[N], c[N];
        reverse_copy(f, f + n, a);
        reverse_copy(g, g + m, b);
        int len = n - m + 1; 
        inv(b, c, len);
        memset(b, 0, m << 2);
        mul(a, c, a, len, len);
        reverse_copy(a, a + len, q);
        fill(q + len, q + n, 0);
        copy(g, g + m, b);
        mul(b, q, b, n, n);
        for(int i = 0; i < m - 1; i++)
            r[i] = (f[i] - b[i] + mod) % mod;
        memset(a, 0, lim << 2);
        memset(b, 0, lim << 2);
        memset(c, 0, lim << 2);
    }
    void sqrt(int *f, int *g, int n) {
        if(n == 1) { g[0] = 1; return; }
        sqrt(f, g, n + 1 >> 1);
        memset(b, 0, n << 2);
        inv(g, b, n);
        mul(f, b, b, n, n);
        for(int i = 0; i < n; i++)
            g[i] = 1ll * (g[i] + b[i]) * inv2 % mod;
    }
    void dev(int *f, int *g, int n) {
        for(int i = 1; i < n; i++)
            g[i - 1] = 1ll * i * f[i] % mod;
        g[n - 1] = 0;
    }
    void idev(int *f, int *g, int n) {
        for(int i = n - 1; i; i--)
            g[i] = 1ll * f[i - 1] * qpow(i, mod - 2) % mod;
        g[0] = 0;
    }
    void ln(int *f, int *g, int n) {
        static int a[N];
        init(n << 1);
        memset(a, 0, lim << 2);
        inv(f, a, n);
        dev(f, g, n);
        mul(g, a, g, n, n);
        idev(g, g, n);
    }
    void exp(int *f, int *g, int n) {
        if(n == 1) { g[0] = 1; return; }
        exp(f, g, n + 1 >> 1);
        ln(g, c, n);
        for(int i = 0; i < n; i++)
            c[i] = (!i + f[i] - c[i] + mod) % mod;
        fill(c + n, c + lim, 0);
        mul(g, c, g, n, n);
        fill(g + n, g + lim, 0); 
    }
    void pow(int *f, int *g, int n, int k) {
        static int a[N];
        memset(a, 0, n << 2);
        ln(f, a, n);
        for(int i = 0; i < n; i++)
            a[i] = 1ll * a[i] * k % mod;
        exp(a, g, n);
    }
    void sin(int *f, int *g, int n) {
        static int a[N], b[N], c[N];
        for(int i = 0; i < n; i++)
            a[i] = 1ll * f[i] * img % mod;
        exp(a, b, n);
        inv(b, c, n);
        for(int i = 0; i < n; i++)
            a[i] = (b[i] - c[i] + mod) % mod;
        int v = qpow(img * 2, mod - 2);
        for(int i = 0; i < n; i++)
            g[i] = 1ll * a[i] * v % mod;
    }
    void cos(int *f, int *g, int n) {
        static int a[N], b[N], c[N];
        for(int i = 0; i < n; i++)
            a[i] = 1ll * f[i] * img % mod;
        exp(a, b, n);
        inv(b, c, n);
        for(int i = 0; i < n; i++)
            a[i] = (b[i] + c[i]) % mod;
        int v = qpow(2, mod - 2);
        for(int i = 0; i < n; i++)
            g[i] = 1ll * a[i] * v % mod;
    }
    void arcsin(int *f, int *g, int n) {
    	static int a[N], b[N], c[N];
    	dev(f, a, n); 
    	mul(f, f, b, n, n);
    	for(int i = 0; i < n; i++)
    		b[i] = (mod - b[i]) % mod;
    	b[0] = (b[0] + 1) % mod;
    	sqrt(b, c, n);
    	memset(b, 0, lim << 2);
    	inv(c, b, n);
    	memset(c, 0, lim << 2);
    	mul(a, b, c, n, n);
    	idev(c, g, n);
	}
	void arctan(int *f, int *g, int n) {
		static int a[N], b[N], c[N];
		dev(f, a, n); 
    	mul(f, f, b, n, n);
    	b[0] = (b[0] + 1) % mod;
    	inv(b, c, n);
    	memset(b, 0, lim << 2);
    	mul(a, c, b, n, n);
    	idev(b, g, n);
	}
} using namespace Polynomial;
posted @ 2024-02-27 20:28  Terac  阅读(17)  评论(0)    收藏  举报