Polynomial
题目描述
题解
对于区间求和,考虑前缀和
记\(S(x)=f(1)+f(2)+····+f(x)\),因为f为n次多项式,多项式求一次和,次数累加一次,所以\(S(x)\)是n+1次多项式
找出n+2个点\(S(1)=f(1),S(2)=S(1)+f(2),···,S(n+2)=S(n+1)+f(n+2)\)
就能求出S(L-1),S(R),则\(ans=S(R)-S(L-1)\)
总时间复杂度\(O(Tmn)\)
点击查看代码
#include<functional>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<complex>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<deque>
#include<map>
#define ll long long
using namespace std;
const int maxn=1e4+101;
const int MOD=9999991;
const int inf=2147483647;
const double pi=acos(-1);
ll read(){
ll x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
return x*f;
}
ll f[maxn],S[maxn],n,k,pre[maxn],ba[maxn];
ll power(ll x,ll y){
ll ans=1;
while(y){
if(y&1)ans=ans*x%MOD;
x=x*x%MOD;y>>=1;
}
return ans;
}
int t;
ll solve(ll x){
ll ans=0;
ll p[maxn],g[maxn];g[0]=p[n+3]=1;
for(int i=1;i<=n+2;i++)g[i]=g[i-1]*(x-i)%MOD;
for(int i=n+2;i>=1;i--)p[i]=p[i+1]*(x-i)%MOD;
for(int i=1;i<=n+2;i++){
ll now=S[i]*g[i-1]%MOD*p[i+1]%MOD;
now=now*pre[i-1]%MOD*ba[n+2-i]%MOD;
ans=(ans+now)%MOD;
}
return ans;
}
int main(){
t=read();
pre[0]=ba[0]=1;
for(int i=1;i<=1005;i++){
pre[i]=(pre[i-1]*i)%MOD;
ba[i]=(ba[i-1]*(-1)*i)%MOD;
}
for(ll i=1005;i>=0;i--){
pre[i]=power(pre[i],MOD-2);
ba[i]=power(ba[i],MOD-2);
}
while(t--){
n=read();k=read();
for(int i=1;i<=n+1;i++)f[i]=read();
for(int i=1;i<=n+2;i++)S[i]=(S[i-1]+f[i-1])%MOD;
ll ans=0;
for(int i=1;i<=k;i++){
int l=read()+2,r=read()+2;
ll r1,l1;
if(r<=n+2)r1=S[r];
else r1=solve(r);
if(l-1<=n+2)l1=S[l-1];
else l1=solve(l-1);
printf("%lld\n",((r1-l1)%MOD+MOD)%MOD);
}
}
return 0;
}