LGP5667 拉格朗日插值2

题目

套一下拉格朗日插值的公式

\[ \begin{aligned} f(m+k)&=\sum_{i=0}^nf(i)\prod_{i\neq j}\frac{m+k-j}{i-j}\\ &=\sum_{i=0}^n\frac{f(i)}{i!(n-i)!(-1)^{n-i}}\frac{(m+k)^{\underline{n+1}}}{(m+k-i)}\\ &=(m+k)^{\underline{n+1}}\sum_{i=0}^n\frac{f(i)}{i!(n-i)!(-1)^{n-i}}\times \frac{1}{m+k-i} \end{aligned} \]

不难看到\(k-i\)\(i\)\(k\),于是这是一个卷积的形式

构造两个函数

\[a_i=\frac{f(i)}{i!(n-i)!(-1)^{n-i}},b_i=\frac{1}{m+i}\]

但是这个\(b\)可能有负下标,我们平移一个\(n\)就好了

代码

#include
#define re register
const int mod=998244353;
const int G[2]={3,(mod+1)/3};
const int maxn=6e5+5;
int n,m,len,a[maxn],b[maxn],rev[maxn],fac[maxn],ifac[maxn];
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
inline int ksm(int a,int b) {
    int S=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)S=1ll*S*a%mod;return S;
}
inline void NTT(int *f,int o) {
    for(re int i=0;i>1,og1=ksm(G[o],(mod-1)/i);
        for(re int t,og=1,l=0;l>1]>>1|((i&1)?len>>1:0);
    NTT(a,0),NTT(b,0);
    for(re int i=0;i=m-n;--i) nw=1ll*nw*i%mod;
    for(re int i=0;i<=n;i++) {
        printf("%d ",1ll*a[i+n]*nw%mod);
        nw=1ll*nw*ksm(m+i-n,mod-2)%mod;
        nw=1ll*nw*(m+i+1)%mod;
    }
    return 0;
}

你可能感兴趣的:(LGP5667 拉格朗日插值2)