2019ICPC 南昌邀请赛 B - Polynomial
\(2019ICPC\) 南昌邀请赛 \(B - Polynomial\)
Define \(f_{(x)} = a_0+a_1 \times x^1 + a_2 \times x^2 +…+ a_n \times x^n\) the number maybe tremendous huge, so take the module of \(9999991\).
For a polynomial, \(XH\) doesn’t know any \(a_i\) , but he knows the value of \(f_{(0)} , f_{(1)}, f_{(2)}…f_{(n)}\). He wants to calculate \(\displaystyle\sum_{i=L}^R f_{(i)}= mod\ 9999991\).
Input
The first line contains a number \(T ( 1 \le T \le 5 )\) ——the number of test cases.
For each test case. The first line contains two integers \(n (1 \le n \le 1000)\) and \(m(1 \le m \le 2000)\) .
The second line contains \(n+1\) integers,representing the value of \(f_{(0)} , f_{(1)}, f_{(2)}…f_{(n)}\)
The next mm lines, each line contains two integers \(L, R\).
\(( 1 \le L \le R \le 9999990)\)
Output
For each test case, output mm lines, each line contains one integer, the value of \(\displaystyle\sum_{i=L}^R f_{(i)}= mod\ 9999991\).
输出时每行末尾的多余空格,不影响答案正确性
样例输入
1
3 2
1 10 49 142
6 7
95000 100000
样例输出
2519
1895570
题解
已知 \(f_x\) ,假设一个 \(S_x=\sum_{i=0}^{x}f_x\) ,那么 \(\displaystyle\sum_{i=L}^R f_{(i)}=S_R-S_{L-1}\)
对于构造 \(S_x\)
\(1^n+2^n+...+x^n\) 是一个 \(x^{n+1}\) 级的式子,具体资料查阅 https://pan.baidu.com/s/1SqZMrZLuOqIp1HQVQejK7g
那么需要在 $ S_x$ 需要在 \(f_x\) 基础上新添加一个项 \(f_{n+1}\),使用拉格朗日插值法进行求解
之后使用递推式 \(S_i=S_{i-1}+f_i\) 求解出一个新的 \(n+1\) 次函数的 \(n+2\) 个点
详细的拉格朗日插值法讲解 https://www.cnblogs.com/crashed/p/13124448.html
注意
- 如果正常的求解会 \(TLE\) ,一些操作需要进行提前处理,减少时间开支。
代码
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const ll mod = 9999991;
const int maxn = 1e3+55;
const int maxxn = 1e7+55;
ll a[maxn];
ll fac[maxn];
ll sub[maxn];
ll pow(ll a,ll b){
ll ret=1;
while(b){
if(b&1)ret=ret*a%mod;
b>>=1;
a=a*a%mod;
}
return ret;
}
ll slove(ll x,int n){
ll ans=0;
if(x<=n)return a[x];
ll xx=1;
for(int i=0;i<=n;++i){
xx=xx*(x-i)%mod;
}
for(int i=0;i<=n;++i){
ll yy=fac[i]*fac[n-i]%mod;
if((n-i)%2)yy=-yy;
ans+=(((a[i]*xx)%mod)*sub[i]%mod)*pow(x-i,mod-2)%mod;
ans=(ans%mod+mod)%mod;
}
return ans;
}
void init(int n){
fac[0]=1;
for(int i=1;i<=n;++i){
fac[i]=fac[i-1]*i%mod;
}
for(int i=0;i<=n;++i){
ll yy=fac[i]*fac[n-i]%mod;
if((n-i)%2)yy=-yy;
sub[i]=pow(yy,mod-2);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
init(n);
for(int i=0;i<=n;++i){
scanf("%lld",&a[i]);
}
a[n+1]=slove((ll)(n+1),n);
init(n+1);
for(int i=1;i<=n+1;++i){
a[i]+=a[i-1];
a[i]%=mod;
}
while(m--){
ll l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",((slove(r,n+1)-slove(l-1,n+1))%mod+mod)%mod);
}
}
return 0;
}