LGP4351题解

很久以前我的某个朋友给过我一道题:

给定 \(f_i,a,b,c,h\),定义 \(A\) 满足:

\[A_{i,j}=i==0?0:j==0?f_i:a\times A_{i-1,j}+b\times A_{i,j-1}+c \]

请求出 \(\sum_{i=1}^{n}\sum_{j=1}^{m}A_{i,j}h^{(i-1)m+j}\) 的值。

当时应该是口胡了一个,把 \(A\) 的每一列看做一个生成函数,容易发现转移是一个卷积,最终答案能够写成 \(F(x)G^n(x)\) 的形式。

随便写写就可以 \(m\log m\log n\) 了。

这道题简直是上述的究极弱化版,只需要求单项。

所以先考虑一个 \(l,t\) 对答案的贡献,容易发现是:

\[\sum_{i=1}^{n}\binom{(n-2)+n-i}{n-i}(l_ib^{n-i}a^{n-1}+t_ia^{n-i}b^{n-1}) \]

这个随便算算就 \(O(n)\) 了,别的地方相当于:

\[\sum_{i=1}^{n-1}\sum_{j=1}^{n-1}\binom{(n-i-1)+(n-j-1)}{n-i-1}a^{n-i-1}b^{n-j-1} \]

\[\sum_{i=0}^{n-2}\sum_{j=0}^{n-2}\binom{i+j}{i}a^ib^i \]

\[\sum_{i=0}^{n}\binom{i+k}{i}b^i \]

不难发现这是一个萌萌卷积,令 \(A(x)=\sum_{i=0}^{n-2}\frac{a^ix^i}{i!},B(x)=\sum_{i=0}^{n-2}\frac{b^ix^i}{i!}\),答案就是 \(\sum_{i=0}^{2n-4}[\frac{x^i}{i!}]A(x)B(x)\)
接下来考虑如何 \(O(n)\)
枚举一个 \(i\),设:

\[F[k]=\sum_{i=0}^{n}\binom{i+k}{i}b^i \]

答案就是 \(\sum_{i=0}^{n}F[i]a^i\)

接下来裂开组合数递推:

\[\sum_{i=0}^{n}\binom{i+(k-1)}{i}b^i+\binom{(i-1)+k}{i-1}b^i \]

\[\sum_{i=0}^{n}\binom{i+(k-1)}{i}b^i+b\sum_{i=0}^{n-1}\binom{i+k}{i}b^i \]

\[F[k]=F[k-1]+b(F[k]-\binom{n+k}{n}b^n) \]

\[F[k]=\frac{F[k-1]-\binom{n+k}{n}b^{n+1}}{1-b} \]

特殊情况,如果 \(b=1\),那么有 \(F[k]=\binom{n+k+1}{n}\)

#include<cstdio>
#include<cctype>
const int M=4e5+5,mod=1e6+3;
int n,a,b,c,ans,x[M],y[M],F[M],fac[M],ifac[M],G[1000][1000];
inline int read(){int n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;}
inline int pow(int a,int b=mod-2){int ans(1);for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;}
inline int C(const int&n,const int&m){return 1ll*ifac[m]*ifac[n-m]%mod*fac[n]%mod;}
inline void calc(const int&n){
	if(b==1){for(int i=0;i<=n;++i)F[i]=C(n+i+1,n);return;}
	const int&x=pow(mod+1-b),&y=mod-pow(b,n+1);F[0]=1ll*(y+1)*x%mod;
	for(int i=1;i<=n;++i)F[i]=(F[i-1]+1ll*C(n+i,n)*y)%mod*x%mod;
}
signed main(){
	n=read()-1;a=read();b=read();c=read();for(int i=0;i<=n;++i)x[i]=read();for(int i=0;i<=n;++i)y[i]=read();
	fac[0]=fac[1]=ifac[0]=ifac[1]=1;for(int i=2;i<=n*2;++i)ifac[i]=1ll*(mod-mod/i)*ifac[mod%i]%mod;
	for(int i=2;i<=n*2;++i)fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*ifac[i]%mod;
	if(c){calc(n-1);for(int i=n-1;i>=0;--i)ans=(1ll*ans*a+F[i])%mod;ans=1ll*ans*c%mod;}
	for(int q(pow(a,n)),p(pow(b,n)),i=n;i>=1;--i){
		ans=(ans+1ll*C(n-1+n-i,n-i)*(1ll*x[i]*q+1ll*y[i]*p))%mod;q=1ll*q*b%mod;p=1ll*p*a%mod;
	}
	printf("%d\n",ans);
}
posted @ 2022-08-23 19:00  Prean  阅读(12)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};