题解:拉格朗日插值裸题
/*
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;
}