upd:修复了代码(之前给成了旧版题目代码)

考虑 $n=1$ 时的做法。此时,$\forall i\ge 1,a_i\times b_0+a_{i-1}\times b_1=0$ 即 $a_i=-\frac{b_1}{b_0}\times a_{i-1}$。这是一个等比数列,令 $k=-\frac{b_1}{b_0}$,则 $a_i=k\times a_{i-1}(i\ge1)$。

设答案为 $S=\sum_{i=0}^\infty a_i$,则 $kS=\sum_{i=1}^\infty a_i$,那么 $S-kS=a_0$,$S=\frac{a_0}{1-k}$。

考虑扩展到 $n=2$。设答案为 $S=\sum_{i=0}^\infty a_i$,则

$$S\times b_0=b_0\sum_{i=0}^\infty a_i$$

$$S\times b_1=b_1\sum_{i=0}^\infty a_i$$

$$S\times b_2=b_2\sum_{i=0}^\infty a_i$$

依题意得,$\sum_{j=0}^2 a_{i-j}\times b_j=0$。所以将上三式相加的结果为 $S\times(b_0+b_1+b_2)=b_0\times a_0+b_0\times a_1+b_1\times a_0$,所以答案为 $S=\frac{b_0\times a_0+b_0\times a_1+b_1\times a_0}{b_0+b_1+b_2}$。

同理可以扩展到 $n>2$,答案为 $S=\frac{\sum_{i=0}^{n-1}\sum_{j=0}^{i+j

可以通过前缀和优化将做到时间复杂度 $O(n)$,但不是本题主要考察内容,所以直接做 $O(n^2)$ 也可以通过。

再给出以下内容的证明。

可以证明,对于任意一个模意义下输入,都存在实数意义下的一个对应数列的答案是收敛的。

首先,我们将递推关系转化为生成函数的形式。设生成函数为:

$$ a(x) = \sum_{i=0}^\infty a_i x^i $$

根据递推关系,我们有:

$$ \sum_{j=0}^m r_j x^j a(x) = p(x) $$

其中,$p(x)$ 是一个多项式。因此,生成函数可以表示为:

$$ a(x) = \frac{p(x)}{g(x)} $$

其中,$g(x) = r_0 + r_1 x + r_2 x^2 + \dots + r_m x^m$ 是递推系数的生成函数。

生成函数 $a(x)$ 的收敛半径由 $g(x)$ 的零点决定,具体来说,收敛半径是 $g(x)$ 的最小模的零点。

如果 $r > 1$,即 $g(x)$ 的所有零点的模都大于1,那么 $a(x)$ 在 $|x| \le r$ 内解析,包括 $x=1$,所以 $\sum_{i=0}^\infty a_i$ 收敛。

反之,如果 $r \le 1$,即 $g(x)$ 至少有一个零点的模小于或等于1,那么 $a(x)$ 在 $x=1$ 处可能发散,即 $\sum_{i=0}^\infty a_i$ 可能发散。

因此,$\sum_{i=0}^\infty a_i$ 收敛当且仅当 $r > 1$。

若我们求出收敛半径在模意义下的值为 $R$,则必然存在一个实数意义下的 $R$ 满足 $R>1$。

#include<bits/stdc++.h>
using namespace std;
const int mod=998'244'353;
struct modint{
    int v;
    modint(int v=0):v(v){}
    modint operator+(modint o){
        int t=v+o.v;
        if(t>=mod){
            t-=mod;
        }
        return t;
    }
    modint operator-(modint o){
        int t=v-o.v;
        if(t<0){
            t+=mod;
        }
        return t;
    }
    modint operator*(modint o){
        return 1ll*v*o.v%mod;
    }
};
modint qpow(modint a,int b){
    modint ans=1;
    while(b){
        if(b&1){
            ans=ans*a;
        }
        a=a*a;
        b>>=1;
    }
    return ans;
}
modint solve(int n,vector<modint> a,vector<modint> b){
    modint ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<=n&&i-j>=0;j++){
            ans=ans+b[j]*a[i-j];
        }
    }
    modint temp=0;
    for(int i=0;i<=n;i++){
        temp=temp+b[i];
    }
    return ans*qpow(temp,mod-2);
}
int main(){
    cin.tie(0)->sync_with_stdio(0);
    int n;
    cin>>n;
    vector<modint> a,b;
    for(int i=0;i<n;i++){
        long double x;
        cin>>x;
        a.push_back(x);
    }
    for(int i=0;i<=n;i++){
        long double x;
        cin>>x;
        b.push_back(x);
    }
    cout<<solve(n,a,b).v<<"\n";
    return 0;
}