题解 P5265 多项式反三角函数

link

这个题很简单,几个板子套一套就做完了,需要了解一些简单微积分。

首先两个结论arcsinx=11x2arctanx=11+x2

证明也很好证,经典隐函数证明。

先看 arcsinx 的,设 siny=x,则

siny=xycosy=1y=1cosyy=11sin2yarcsinx=11x2

arctanx 同理,设 tany=x,则tany=xysec2y=1y=1sec2yy=11+tan2yarctanx=11+x2

回到这题,设 G=arcsinF,则G=arcsinF=F1F2

积回来

G=F1F2dx

同理,设 G=arctanF,则G=arctanF=F1+F2

积回来

G=F1+F2dx 套一下多项式求导,积分,开根,乘法,求逆即可。

#include <bits/stdc++.h>
using namespace std;
namespace IO {
    //read and write
} using namespace IO;
const int N = 2.7e5 + 10;
namespace Polynomial {
    const int mod = 998244353, G = 3, Gi = 332748118, inv2 = 499122177;
    int lim, rev[N], a[N], b[N], c[N];
    int qpow(int n, int k) {
        int res = 1;
        for(; k; n = 1ll * n * n % mod, k >>= 1)
            if(k & 1) res = 1ll * res * n % 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 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 invdev(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 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);
        invdev(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);
        invdev(b, g, n);
    }
} using namespace Polynomial;
int n, type, f[N], g[N];
int main() {
    n = read(), type = read();
    for(int i = 0; i < n; i++)
        f[i] = read();
    if(!type) arcsin(f, g, n);
    else arctan(f, g, n);
    for(int i = 0; i < n; i++)
        write(g[i]), putc(' ');
    flush();
    return 0;
}
posted @   Terac  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示