版权声明:转吧转吧这条东西只是来搞笑的。。 https://blog.csdn.net/jpwang8/article/details/88956990
Description
求
其中
Solution
不会做(艹皿艹 ),怒orz题解
记
,那么
我们把
二项式定理展开,那么就是
然后发现最右边就是
,于是我们就可以愉快地k2递推这个东西了。。
然后当r=1的时候上面就不成立了,这个时候求自然数幂和就行。
拉格朗日插值:
对于自然数幂和可以发现x都是连续的,那么就变成了下面这个样子
分子刚好就是前缀后缀积,分母刚好就是阶乘了。自然数幂和的前k项可以线性筛,阶乘和逆元可以线性求,前缀后缀积同理,那么整个做下来都是O(n)的
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
typedef long long LL;
const int MOD=1e9+7;
const int N=200005;
LL s[N],fac[N],inv[N],pre[N],nex[N];
LL ksm(LL x,LL dep) {
LL res=1;
x=(x%MOD+MOD)%MOD;
for (;dep;dep>>=1) {
(dep&1)?(res=res*x%MOD):0;
x=x*x%MOD;
}
return res;
}
void solve1(LL n,int k) {
LL ans=0; n%=MOD;
rep(i,1,k+1) s[i]=(s[i-1]+ksm(i,k))%MOD;
pre[0]=n; nex[k+2]=1;
rep(i,1,k+1) pre[i]=pre[i-1]*(n+MOD-i)%MOD;
drp(i,k+1,0) nex[i]=nex[i+1]*(n+MOD-i)%MOD;
rep(i,0,k+1) {
LL fz=((i>0)?(pre[i-1]):1)*(nex[i+1])%MOD;
LL fm=fac[i]*fac[k+1-i]%MOD;
LL tmp=fz*ksm(fm,MOD-2)%MOD*s[i]%MOD;
if ((k+1-i)&1) tmp=(MOD-tmp);
ans=(ans+tmp)%MOD;
}
printf("%lld\n", ans);
}
void solve2(LL n,LL k,LL r) {
s[0]=(ksm(r,n+1)+MOD-r)*ksm(r-1,MOD-2)%MOD;
rep(i,1,k) {
s[i]=(ksm(r,n+1)*ksm(n,i)%MOD+MOD-r)%MOD;
rep(j,0,i-1) {
LL tmp=fac[i]*inv[j]%MOD*inv[i-j]%MOD*(s[j]+MOD-r)%MOD;
if ((i-j)&1) tmp=(MOD-tmp)%MOD;
s[i]=((s[i]+tmp)%MOD+MOD)%MOD;
}
s[i]=s[i]*ksm(r-1,MOD-2)%MOD;
}
s[k]=(s[k]%MOD+MOD)%MOD;
printf("%lld\n", s[k]);
}
int main(void) {
freopen("data.in","r",stdin);
fac[0]=fac[1]=inv[0]=inv[1]=1;
rep(i,2,N-1) {
fac[i]=fac[i-1]*i%MOD;
inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
}
rep(i,2,N-1) inv[i]=inv[i-1]*inv[i]%MOD;
int T; scanf("%d",&T);
for (;T--;) {
LL n,r,k; scanf("%lld%lld%lld",&n,&k,&r);
r%=MOD;
if (r==1) solve1(n,k);
else solve2(n,k,r);
}
return 0;
}