题解:P11617 递推

前言

第一次在 OI 中见到求数列极限的题,有点意思。

但是为什么会过这么多人啊。

思路分析

做一点尝试:

\[\sum_{i=m} \sum_{j=0}^{m} r_ja_{i-j}=0 \]

然后对于相同的 \(a_i\),合并同类项:

\[\sum_{i=m}\sum_{j=0}^{m} r_ja_i + \sum_{i=0}^{m-1}\sum_{j=0}^{i} r_{m-j}a_i=0 \]

然后凑出我们的目标:

\[\sum_{i=0} a_i=\sum_{i=0}^{m-1}a_i-\frac{\sum_{i=0}^{m-1}\sum_{j=0}^{i} r_{m-j}a_i}{\sum_{i=0}^{m} r_i} \]

做完了,不难发现可以 \(O(m^2)\) 计算和柿。

其实画一个草表也能看出来怎么做,以 \(m=3\) 为例:

代码实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
inline int binpow(int a,int b){
	if(!b) return 1;
	int res=binpow(a,b/2);
	if(b&1) return res*res%mod*a%mod;
	else return res*res%mod;
}
int n,a[30005],r[30005],ans,sumr,suma;
signed main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
		ans=(ans+a[i])%mod;
	}
	for(int i=0;i<=n;i++){
		cin>>r[i];
		sumr=(sumr+r[i])%mod; 
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<=i;j++){
			suma=(suma+r[n-j]*a[i]%mod)%mod;
		}
	}
	ans=(ans-suma*binpow(sumr,mod-2)%mod+mod)%mod;
	cout<<ans;
	return 0;
}
posted @ 2025-02-02 12:15  _Kenma  阅读(17)  评论(0)    收藏  举报