拉格朗日插值法

 

拉格朗日插值法,原理请看百度百科。

题目:落谷 P4781 【模板】拉格朗日插值

 1 #include
 2 using namespace std;
 3 typedef long long LL;
 4 const int N=2e3+10;
 5 const int MOD=998244353;
 6 int n,k,x[N],y[N];
 7 
 8 int power(LL x,LL p,LL MOD) {
 9     LL ret=1;
10     for (;p;p>>=1) {
11         if (p&1) ret=ret*x%MOD;
12         x=x*x%MOD;
13     }
14     return (int)ret;
15 }
16 
17 int Lagrange() {
18     int ret=0;
19     for (int i=1;i<=n;i++) {
20         int up=1,down=1;
21         for (int j=1;j<=n;j++) {
22             if (i==j) continue;
23             up=(LL)up*((k-x[j])%MOD+MOD)%MOD;  //分子 
24             down=(LL)down*((x[i]-x[j])%MOD+MOD)%MOD;  //分母 
25         }
26         int tmp=(LL)y[i]*up%MOD*power(down,MOD-2,MOD)%MOD;
27         ret=(ret+tmp)%MOD;
28     }
29     return ret;
30 }
31 
32 int main()
33 {
34     cin>>n>>k;
35     for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
36     cout<endl;
37     return 0;
38 }

南昌拉格朗日插值b题。

题目链接:https://nanti.jisuanke.com/t/40254

(此题要求该多项式l-r的值的和,那么我们可以先算出该多项式的和多项式,注意:n次多项式的和多项式是n+1次的故要先算出第n+1项再用拉格朗日插值法求和多项式)。

AC代码:

 1 #include 
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 2e3+10;
 5 const int p = 9999991;
 6 ll pre[N],suf[N],ifac[N],sum[N],a[N],fac[N];
 7 ll power(ll x,ll t)
 8 {
 9     ll ret=1;
10     while(t)
11     {
12         if (t&1) ret=ret*x%p;
13         x=x*x%p;t>>=1;
14     }
15     return ret;
16 }
17 void init(int n)
18 {
19     fac[0]=1;
20     for (int i = 1; i <= n+2; ++i)
21     {
22         fac[i]=fac[i-1]*i%p;
23     }
24     for (int i = 0; i <= n+2; ++i)
25     {
26         ifac[i]=power(fac[i],p-2);
27     }
28 }
29 int Lagrange(ll *y,ll n,ll k)
30 {
31     ll ans=0;pre[0]=1;suf[n+1]=1;
32     for (int i = 0; i <= n; ++i) pre[i+1]=1ll*pre[i]*(k-i)%p;
33     for (int i = n; i >= 0; --i) suf[i]=1ll*suf[i+1]*(k-i)%p;
34 
35     for (int i = 0; i <= n; ++i)
36     {
37         ll temp=y[i]*pre[i]%p*suf[i+1]%p*ifac[i]%p*ifac[n-i]%p;
38         if ((n-i)&1) ans=(ans-temp)%p;
39         else ans=(ans+temp)%p;
40     }
41     return (ans%p+p)%p;
42 }
43 int main(int argc, char const *argv[])
44 {
45     ll t,n,m,l,r;
46     cin>>t;
47     init(1020);
48     while(t--)
49     {
50         cin>>n>>m;
51         for (int i = 0; i <= n; ++i)
52         {
53             cin>>a[i];
54         }
55         a[n+1]=Lagrange(a,n,n+1);
56         sum[0]=a[0]%p;
57         for (int i = 1; i <= n+1; ++i)
58         {
59             sum[i]=(sum[i-1]+a[i])%p;
60         }
61         for (int j = 1; j <= m; ++j)
62         {
63             cin>>l>>r;
64             ll ans=Lagrange(sum,n+1,r)-Lagrange(sum,n+1,l-1);
65             cout<<(ans+p)%p<<"\n";
66         }
67     }
68     return 0;
69 }

 

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