拉格朗日插值法模板

最近多校碰到了有关拉格朗日插值法的题目,就系统学了下,具体解释在上一篇博客,下面给出模板。(以CF622F为例)

模板代码:

#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define MOD 1000000007
#define PI acos(-1.0)
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

ll n,k,ans,fac[N],y[N];

ll qp(ll a,ll b) {
    ll s=1;
    while(b) {
        if(b&1) s=s*a%MOD;
        a=a*a%MOD,b>>=1;
    }
    return s;
}

ll sv() {
    fac[0]=fac[1]=1,y[1]=1;
    for(int i=2;i<=k+2;i++) fac[i]=fac[i-1]*i%MOD;///预处理阶乘
    for(int i=2;i<=k+2;i++) y[i]=(y[i-1]+qp(i,k))%MOD;///预处理求出每一项的结果
    if(n<=k+2)  return y[n];
    ll sum=1,sig;
    for (ll i=n-k-2;i<=n-1;i++) sum=sum*i%MOD;
    for(ll i=1;i<=k+2;i++) {///k+1项的多项式有k+2项
        ll fz=sum*qp(n-i,MOD-2)%MOD;///分子
        ll fm=qp(fac[i-1]*fac[k+2-i]%MOD,MOD-2);///分母
        if((k+2-i)%2==0) sig=1;///正负号
        else sig=-1;
        ans=(ans+MOD+sig*y[i]*fz%MOD*fm%MOD+MOD)%MOD;
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>k;
    cout<<sv()<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianwei0822/article/details/81153981
今日推荐