Description
Solution
设DP方程:
fi
表示做到i且i位为0的和期望,
gi
表示做到i且i位为0的和期望平方,
设
sum(i,j)=(i+j)∗(i−j+1)/2
先看一下f怎么求,
fi=∑j=0i−1(fj+sum(j+1,i−1))∗(1−pj)∗∏k=j+1i−1pk
这个很好理解,
有公式: (a+b)2=a2+b2+2ab
所有g的求法也和上面的差不多,就是加上了完全平方公式,
gi=∑j=0i−1(gj+sum(j+1,i−1)2+2sum(j+1,i−1)∗fj)∗(1−pj)∗∏k=j+1i−1pk
最后输出 gn+1
复杂度: O(n2) (辣鸡只会70分)
Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=2e6+50,mo=998244353;
int read(LL &n)
{
char ch=' ';LL q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int n,m;
LL p[N],p1[N];
LL ps[N],psn[N];
LL f[N],g[N];
int ts[N];
LL ksm(LL q,LL w)
{
LL a=q%mo,ans=1;
while(w)
{
if(w%2) ans=(ans*a)%mo;
a=(a*a)%mo;w=w/2;
}
return(ans);
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
LL q,w,yb=ksm(100,mo-2);
n=read(q);
psn[0]=ps[0]=1;p[0]=0;p1[0]=1;
fo(i,1,n)p1[i]=(100-read(p[i]))*yb%mo,p[i]=p[i]*yb%mo;
p[n+1]=0;p1[n+1]=1;
fo(i,1,n+1)
{
ts[i]=ts[i-1];
if(p[i])ps[i]=p[i]*ps[i-1]%mo;else ps[i]=ps[i-1],ts[i]++;
psn[i]=ksm(ps[i],mo-2);
}
ts[n+1]--;
fo(i,1,n+1)
{
fo(j,0,i-1)if(ts[i-1]-ts[j]<1)
{
q=(i-j)*(i-j-1)/2%mo;w=(i-j)*(i-j-1)%mo;
f[i]=(f[i]+(f[j]+q)*p1[j]%mo*(ps[i-1]*psn[j]%mo)%mo)%mo;
g[i]=(g[i]+(g[j]+f[j]*w%mo+q*q%mo)%mo*p1[j]%mo*(ps[i-1]*psn[j]%mo)%mo)%mo;
}
}
printf("%lld\n",g[n+1]);
return 0;
}