CF1696E 题解

CF1696E

思路

数学题。

答案是唯一的。操作过程从左上到右下不可逆。每个点操作次数的贡献即每个点数的最大值。

类似于递推:

\[dp_{i,0}=dp_{0,i}=1 \]

\[dp_{i,j}=dp_{i-1,j}+dp_{i,j-1} \]

则答案为划定范围内所有 \(dp\) 数组值的和。

但这样是 \(O(n^2)\) 的。

又发现斜着看这其实是杨辉三角。

\[C_{i+j}^{i}=dp_{i,j} \]

\[ans=\sum_{i=0}^n \sum_{j=0}^{a_i-1} C_{i+j}^{i}=\sum_{i=0}^n \sum_{j=0}^{a_i-1} dp_{i,j} \]

经过打表和 OEIS,发现:

\[\sum_{j=0}^{a_i-1} dp_{i,j}=dp_{i+1,a_i-1} \]

补证明:

\[\sum_{j=0}^{a_i-1} dp_{i,j}=dp_{i,0}+\sum_{j=1}^{a_i-1}dp_{i,j}=dp_{i+1,0}+\sum_{j=1}^{a_i-1}dp_{i,j}=dp_{i+1,a_i -1} \]

于是可以 \(O(n)\)

code

int n,a[maxn],ans;
int pw[maxn],inv[maxn];
inline int ksm(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
int C(int m,int n){
	return pw[m]*inv[n]%mod*inv[m-n]%mod;
}

signed main(){
	n=read();
	for(int i=0;i<=n;i++)a[i]=read();
	pw[0]=inv[0]=1;
	for(int i=1;i<=maxn-10;i++)pw[i]=pw[i-1]*i%mod,inv[i]=ksm(pw[i],mod-2);
	for(int i=0;i<=n;i++)ans+=C(a[i]+i,i+1),ans%=mod;
	printf("%lld\n",ans);
}

posted @ 2024-05-10 19:58  yhddd  阅读(7)  评论(0编辑  收藏  举报