P5148 题解
思路
先把原式写成数学形式,即
这里
完了?
不,还没有
本体涉及到有理数取模,要求 bu hui)用扩展欧几里得算法求逆元,习惯(zhi hui)用线性求逆元,但因为有阶乘的存在,时间复杂度其实都是
坑点
-
-
循环里的
a_{i} 不是读入的a_{i} ,读入的a_{i} 代表f(q) 里的a_{i} 。 -
不要以为只有
q 需要开 long long ,所有的(n,m,k,a_{i} 除外 )都要开
代码
#include<bits/stdc++.h>//万能头
using namespace std;
#define ll long long
const int p = 1e9 + 7;
ll n,m,k,q,a[500005],ans,s = 1,inv[500005];//十年OI一场空,不开long long见祖宗
ll C(int x,int y)//组合
{
ll w = 1;
for(int i = x - y + 1;i <= x;i++)//从 (n - k + 1) 至 n 的积,把(n - k)!约掉了
w = (w * i) % p;
for(int i = 1;i <= y;i++)
w = (w * inv[i]) % p;//k!的逆元
return w;
}
int main()
{
cin>>n>>m>>k>>q;
q %= p;
inv[1] = 1;//初始化逆元
for(ll i = 2;i <= n;i++)//线性求逆元
inv[i] = (p - p / i) * inv[p % i] % p;
for(int i = 0;i <= m;i++)
cin>>a[i];
for(int i = 0;i <= m;i++)
ans = (ans + a[i] * s) % p,s = (s * q) % p;//f(q)
cout<<ans * C(n,k) % p<<endl;//最后也要对p取模
}