题目大意
求
k=0∑nf(k)×xk×(kn)(modp)
其中 n,x,p 为给定整数,f(k) 为给定多项式 f(k)=∑i=0maiki 。
n,x,p,ai≤109, m≤min(n,1000)
1s
题解
转了一圈,这题的推法似乎多种多样啊。。。(虽然本质相同
就记录一个我觉得比较好的吧。
核心思路就是 ki(kn) 写成下降幂多项式,然后发现有奇效。
设 f(k)=∑i=0maiki 转化成下降幂多项式为
f(k)=i=0∑mbiki=i=0∑mbi(k−i)!k!
代入原式有
k=0∑nf(k)×xk×(kn)=k=0∑ni=0∑mbi(k−i)!k!×xk×k!(n−k)!n!=k=0∑ni=0∑mbi×xk×(n−k)!(k−i)!n!=k=0∑ni=0∑mbi(n−i)!n!×xk×(n−kn−i)=i=0∑mbi(n−i)!n!k=i∑nxk(n−kn−i)=i=0∑mbini(x+1)n−i
这个东西 O(m) 循环一遍就好了,(x+1)n−i 可以预处理也可以快速幂。
至于 bi 的求法,也就是多项式转下降幂多项式,根据
xi=j=0∑iS(i,j)xj
(其中 S(i,j) 表示第二类斯特林数)可得
i=0∑maixi=i=0∑maij=0∑iS(i,j)xj=j=0∑xji=j∑maiS(i,j)
因此预处理第二类斯特林数,然后 bj=∑i=jmaiS(i,j) 即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std;
typedef long long LL;
const int maxm=1005;
LL n,x,mo,a[maxm]; int m;
LL S[maxm][maxm]; void S_pre(int n) { fo(i,0,m) { fo(j,1,i-1) S[i][j]=(S[i-1][j-1]+j*S[i-1][j])%mo; S[i][i]=1; } }
LL b[maxm]; void FFP() { fo(i,0,m) fo(j,i,m) (b[i]+=a[j]*S[j][i])%=mo; }
LL Pow(LL x,LL y) { LL re=1; for(; y; y>>=1, x=x*x%mo) if (y&1) re=re*x%mo; return re; }
int main() { freopen("problem.in","r",stdin); freopen("problem.out","w",stdout); scanf("%lld %lld %lld %d",&n,&x,&mo,&m); fo(i,0,m) scanf("%lld",&a[i]); S_pre(m); FFP(); LL ndown=1, xpow=1, ans=0; fo(i,0,m) { (ans+=b[i]*xpow%mo*ndown%mo*Pow(x+1,n-i))%=mo; (xpow*=x)%=mo; (ndown*=n-i)%=mo; } printf("%lld\n",ans); }
|