拉格朗日插值

​  给你 n 个点:(x1,y1),(x2,y2),,(xn,yn),求经过这 n 个点的n1次多项式 L(x)

​  直接高斯消元是 O(n3) 的。

L(x)=i=1nyij=1,jinxxjxixj=i=1nyixx1xix1xxi1xixi1xxi+1xixi+1xxnxixn

​  设 A(x)=ni=1(xxi),Bi(x)=A(x)xxi,Ci(x)=Bi(x)Bi(xi)

​  可以看出

Ci(x)=xx1xix1xxi1xixi1xxi+1xixi+1xxnxixn={1    (x=xi)0    (x=xj,ji)

​  因为当 x=xi 时每一项的分子都等于分母,当 x=xj(ji) 时有一项的分子为 0

​  那么

L(x)=i=1nyiCi(x)

​  这样就可以 O(n2) 算出来了。

代码

​   t 个点,插出t1次多项式。

void solve()
{
    memset(c,0,sizeof c);
    c[0]=1;
    memset(ans,0,sizeof ans);
    for(i=1;i<=t;i++)
        for(j=t;j>=0;j--)
        {
            (c[j+1]+=c[j])%=p;
            (c[j]=-c[j]*x[i])%=p;
        }
    for(i=1;i<=t;i++)
    {
        memcpy(d,c,sizeof d);
        memset(b,0,sizeof b);
        for(j=t;j>=0;j--)
        {
            b[j]=d[j+1];
            d[j]=(d[j]+d[j+1]*x[i])%p;
            d[j+1]=0;
        }
        ll s=0,px=1;
        for(j=0;j<=t;j++)
        {
            s=(s+px*b[j])%p;
            px=px*x[i]%p;
        }
        s=fp(s,p-2)*y[i]%p;
        for(j=0;j<=t;j++)
            b[j]=b[j]*s%p;
        for(j=0;j<=t;j++)
            ans[j]=(ans[j]+b[j])%p;
    }
}

​   n 个点,求f(m)

void solve()
{
    ll ans=0;
    for(i=1;i<=n;i++)
    {
        ll s1=1,s2=1;
        for(j=1;j<=n;j++)
            if(j!=i)
            {
                s1=(s1*(m-x[j]))%p;
                s2=(s2*(x[i]-x[j]))%p;
            }
        ans=(ans+y[i]*s1%p*fp(s2,p-2)%p)%p;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值