【计蒜客】2019 南昌邀请赛 B题

题解:拉格朗日插值裸题

/*
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;
}
发布了119 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_40727946/article/details/94124660