題解:拉格朗日插值裸題
/*
2019 ICPC南昌區域賽 B題
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//mod一定要是質數
const int mod=9999991;
int pv[2000]; //前幾項, 前面無效值用0佔位
int st=1,ed; //使用上面數組下標爲[st,ed]的數據
ll fac[2000],inv[2000],facinv[2000];
ll pre[2000],saf[2000];
//預處理: fac[]階乘, inv[]逆元, facinv[]階乘逆元
//只需要main函數內調用一次!
void init()
{
fac[0]=inv[0]=facinv[0]=1;
fac[1]=inv[1]=facinv[1]=1;
for(int i=2;i<ed+3;++i)
{
fac[i]=fac[i-1]*i%mod;
inv[i]=mod-(mod/i*inv[mod%i]%mod);
facinv[i]=facinv[i-1]*inv[i]%mod;
}
}
//計算第x0項的值
//複雜度O(ed-st)
ll cal(ll x0)
{
int n=ed-st;
x0=((x0%mod)+mod)%mod;
pre[0]=((x0-st)%mod+mod)%mod;
saf[n]=((x0-st-n)%mod+mod)%mod;
for(int i=1;i<=n;++i)
{
pre[i]=((pre[i-1]*(x0-st-i))%mod+mod)%mod;
saf[n-i]=((saf[n-i+1]*(x0-st-n+i))%mod+mod)%mod;
}
ll res=0;
for(int i=0;i<=n;++i)
{
ll fz=1;
if(i!=0)fz=fz*pre[i-1]%mod;
if(i!=n)fz=fz*saf[i+1]%mod;
ll fm=facinv[i]*facinv[n-i]%mod;
if((n-i)&1)fm=mod-fm;
(res+=pv[i+st]*(fz*fm%mod)%mod)%=mod;
}
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n,q;
memset(pv,0,sizeof(pv));
cin>>n>>q;
ed=n+1;
for(int i=1;i<=n+1;i++)
{
cin>>pv[i];
}
init();
pv[n+2]=cal(n+2);
for(int i=1;i<=n+2;i++)
{
pv[i]=(pv[i]+pv[i-1])%mod;
}
ed=n+2;
init();
while(q--)
{
int l,r;
cin>>l>>r;
ll ans=(cal(r+1)-cal(l)+mod)%mod;
cout<<ans<<endl;
}
}
return 0;
}