将期望表达式按定义写出后提取公因子,具体步骤:

为了书写方便,令pi=1/pip_i = 1 / p_iqi=j=1i(1pj) q_i = \prod_{j=1}^i{(1 - p_j)},特别的令q0=1q_0 = 1

Ex=p1×1+q1p2×2+...+qn1pn×nE_x = p_1 \times 1 + q_1 p_2 \times 2 + ... + q_{n - 1} p_n \times n

+qn p1×(n+1)+qn q1p2×(n+2)+...+qn qn1pn×(n+n)+ q_n~p_1 \times (n + 1) + q_n~q_1 p_2 \times (n + 2) + ... + q_n~q_{n - 1} p_n \times (n + n)

+qn2 p1×(2n+1)+qn2 q1p2×(2n+2)+...+qn2 qn1pn×(2n+n)+ {q_n}^2~p_1 \times (2n + 1) + {q_n}^2~q_1 p_2 \times (2n + 2) + ... + {q_n}^2~q_{n - 1} p_n \times (2n + n)

+...+...

单独对i[1,n]i\in[1,n]的列求和

Ex=i=1nj=0+(qnj qi1 pi×(jn+i))E_x = \sum_{i=1}^n \sum_{j=0}^{+\infty} ({q_n}^j~q_{i - 1}~p_i \times (jn + i))

=i=1n(qi1 pij=0+(qnj×(jn+i)))= \sum_{i=1}^n (q_{i - 1}~p_i \sum_{j=0}^{+\infty} ({q_n}^j \times (jn + i)))

现在只需求出j=0+(qnj×(jn+i))\sum_{j=0}^{+\infty} ({q_n}^j \times (jn + i))

很明显这是一个等比数列×\times等差数列,用高中学的错位相减即可求和,求和后再求下极限就可以得出结果式子了。

(这个求和应该不用写了吧,用markdown不怎么好写,要把所有项列出来,不会的可以求助下高中数学老师)

最终对于i[1,n]i\in[1,n]的所有项都可以先预处理后在O(1)O(1)复杂度内得到结果,总时间复杂度O(n)O(n)

const int N = 1e5 + 10, M = 1e6 + 10;

int p[N];

int quickpow(int x, int k)
{
    int res = 1;
    while(k)
    {
        if(k & 1) res = res * x % mod1;
        k >>= 1;
        x = x * x % mod1;
    }
    return res;
}

int inv(int x)
{
    return quickpow(x, mod1 - 2);
}

void solve(int Case)
{
    int n = read();
    for(int i = 1;i <= n;i ++) p[i] = read();
    for(int i = 1;i <= n;i ++)
        p[i] = p[i] * inv(100) % mod1;
    int q = 1;
    for(int i = 1;i <= n;i ++)
        q = q * ((1 + mod1 - p[i]) % mod1) % mod1;

    int res = 0;
    int temp = n * q % mod1 * inv((1 + mod1 - q) % mod1) % mod1 * inv((1 + mod1 - q) % mod1) % mod1;
    for(int i = 1, last = 1;i <= n;i ++)
    {
        res = (res + (i * inv((1 + mod1 - q) % mod1) % mod1 + temp) % mod1 * p[i] % mod1 * last % mod1) % mod1;
        last = last * ((1 + mod1 - p[i]) % mod1) % mod1;
    }

    printf("%lld\n", res);
}

signed main()
{
//    ios;
    int t = 1;// t = read();
    for(int i = 1;i <= t;i ++) solve(i);
    return 0;
}