https://ac.nowcoder.com/acm/contest/8051/D
一个长度为(n)的数列满足(sum a_ile m),它的贡献为((m-sum a_i)(prod (a_i+K)^2-K^2))
求所有的这样的数列的贡献和。
(n,m,Kle 10^6)
生成函数吼题。
答案为(sum(m-j)[x^j](sum(i+2K)ix^i)^n)
先用个比较优美的方式表示(sum(i+2K)ix^i):
(sum(i+2K)ix^i=sum i(i+1)x^i+sum(2K-1)x^i=frac{2x}{(1-x)^3}+frac{2K-1}{(1-x)^2})
(总结一下:当要把形如(sum_iF(i)x^i)的式子化成封闭的优美形式时,可以把(F(x))变成上升幂多项式)
继续推:
((frac{2x}{(1-x)^3}+frac{2K-1}{(1-x)^2})^n=frac{2^nx^n}{(1-x)^{2n}}(frac{1}{1-x}+c)^n=2^nsum_{i=0}^nfrac{x^n}{(1-x)^{2n+i}}inom{n}{i}c^{n-i})
(c)为常数。
(sum_{j=n}^m(m-j)[x^j]2^nsum_{i=0}^nfrac{x^n}{(1-x)^{2n+i}}inom{n}{i}c^{n-i}=2^nsum_{j=n}^m(m-j)sum_{i=0}^ninom{i+j+n-1}{i+2n-1}inom{n}{i}c^{n-i}=2^nsum_{i=0}^ninom{n}{i}c^{n-i}sum_{j=n}^m(m-j)inom{i+j+n-1}{i+2n-1})
(sum_{j=n}^m(m-j)inom{i+j+n-1}{i+2n-1}=sum_{j=n}^msum_{k=j+1}^minom{i+j+n-1}{i+2n-1}=sum_{k=n}^msum_{j=n}^{k-1}inom{i+j+n-1}{i+2n-1}=inom{i+n+m}{i+2n+1})
所以答案为(2^nsum_{i=0}^ninom{n}{i}c^{n-i}inom{i+n+m}{i+2n+1})
可以(O(n))解决。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 2000010
#define ll long long
#define mo 998244353
ll qpow(ll x,ll y=mo-2){
ll r=1;
for (;y;y>>=1,x=x*x%mo)
if (y&1)
r=r*x%mo;
return r;
}
ll fac[N],ifac[N];
void initC(int n){
fac[0]=1;
for (int i=1;i<=n;++i)
fac[i]=fac[i-1]*i%mo;
ifac[n]=qpow(fac[n]);
for (int i=n-1;i>=0;--i)
ifac[i]=ifac[i+1]*(i+1)%mo;
}
ll C(int m,int n){
if (m<n) return 0;
return fac[m]*ifac[n]%mo*ifac[m-n]%mo;
}
int n,m,k;
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d%d%d",&n,&m,&k);
initC(m*2+n*2);
ll c=(2*k-1+mo)*qpow(2)%mo,invc=qpow(c);
ll ans=0;
// for (int j=n;j<=m;++j){
// ll s=0;
// for (int i=0;i<=n;++i)
// (s+=C(n,i)*qpow(c,n-i)%mo*C(i+j+n-1,j-n))%=mo;
// (ans+=s*(m-j))%=mo;
// }
// ans=ans*qpow(2,n)%mo;
for (int i=0;i<=n;++i){
ll s=C(i+n+m,i+2*n+1);
// for (int k=n;k<=m;++k)
// s+=C(i+n+k-1,i+2*n);
// s%=mo;
(ans+=C(n,i)*qpow(c,n-i)%mo*s)%=mo;
}
ans%=mo;
ans=ans*qpow(2,n)%mo;
printf("%lld
",ans);
return 0;
}