拉格朗日插值 2

题目:

给你一个次数不超过的函数在点上的取值,以及一个整数,就的值。

答案对取模。

题解:

当然这题可以推广成很多题,例如:求中的连续的m项。

我们首先要会普通的拉格朗日插值,

还要会在取值连续时的做法,

你还要会多项式乘法,由于本题对取模,所以用,元根是

前置知识有点多啊啊啊

由于是连续的点,即
$$

我们设 为多项式

我们可以先把等多项式用拉格朗日插值的方法预处理出来,再用把这些多项式乘起来得到

代码:

#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
const int mod=998244353;
const int gi=3;
const int N=1e6+5;
int n,m,bit,y[N],jc1[N],jc2[N],inv1[N],inv2[N],f[N],g[N],rev[N];
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
    int ret=0,f=0;char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
    if(f)return -ret;return ret;
}
int kuai(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b%2==1)res=res*a%mod;
        a=a*a%mod;
        b=b/2;
    }
    return res;
}
void Pre(int n,int m)
{
    jc1[0]=jc2[0]=1;
    for(int i=1;i<=n;i++)
    {
        jc1[i]=jc1[i-1]*i%mod;
        jc2[i]=jc2[i-1]*(m+i)%mod;
    }
    inv1[n]=kuai(jc1[n],mod-2);
    inv2[n]=kuai(jc2[n],mod-2);
    for(int i=n-1;i>=0;i--)
    {
        inv1[i]=inv1[i+1]*(i+1)%mod;
        inv2[i]=inv2[i+1]*(m+i+1)%mod;
    }
}
void work(int n)
{
    for(int i=1;i<n;i++)
        rev[i]=(rev[i>>1]>>1)|((i&1)<<bit);
}
void ntt(int *a,int n,int op)
{
    for(int i=1;i<n;i++)
        if(i<rev[i])swap(a[i],a[rev[i]]);
    int w,ii,wn,t;
    for(int i=2,ii=1;i<=n;i*=2,ii*=2)
    {
        wn=kuai(gi,(mod-1)/i);
        for(int j=0;j<n;j+=i)
        {
            w=1;
            for(int k=0;k<ii;k++)
            {
                t=(long long)w*a[j+k+ii]%mod;
                a[j+k+ii]=(a[j+k]-t+mod)%mod;
                a[j+k]=(a[j+k]+t)%mod;
                w=(long long)w*wn%mod;
            }
        }
    }
    if(op==-1)
    {
        reverse(a+1,a+n);
        int inv=kuai(n,mod-2);
        for(int i=0;i<n;i++)a[i]=(long long)a[i]*inv%mod;
    }
}
signed main()
{
    n=read();m=read();
    for(int i=0;i<=n;i++)y[i]=read();
    Pre(n*2,m-n);
    int s=1,len=n*2;
    while(s<=len)
    {
        s=s*2;
        bit++;
    }
    bit--;
    work(s);
    for(int i=0;i<=n;i++)
    {
        f[i]=y[i]*inv1[i]%mod;
        g[i]=((i&1)?mod-1:1)*inv1[i]%mod;
    }
    ntt(f,s,1);
    ntt(g,s,1);
    for(int i=0;i<s;i++)f[i]=f[i]*g[i]%mod;
    ntt(f,s,-1);
    s=s*2;
    bit++;
    work(s);
    for(int i=n+1;i<s;i++)f[i]=0;
    for(int i=0;i<=n*2;i++)g[i]=inv2[i];
    for(int i=n*2+1;i<s;i++)g[i]=0;
    ntt(f,s,1);
    ntt(g,s,1);
    for(int i=0;i<s;i++)f[i]=f[i]*g[i]%mod;
    ntt(f,s,-1);
    for(int i=0;i<=n;i++)printf("%lld ",f[n+i]*jc2[n+i]%mod);
    return 0;
}
xuxuxuxuxu 文章被收录于专栏

信息学竞赛

全部评论

相关推荐

11-14 16:13
已编辑
重庆科技大学 测试工程师
Amazarashi66:不进帖子我都知道🐮❤️网什么含金量
点赞 评论 收藏
分享
09-29 11:19
门头沟学院 Java
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务