【JZOJ 4938】 序列 70分做法

来源:互联网 发布:javascript indexof 编辑:程序博客网 时间:2024/05/21 03:26

Description

这里写图片描述
这里写图片描述

Analysis


如图,可能的状态转移
我比赛是想的辣鸡dp是从后往前,f[i][j]设dp到第i列,数为j的平方和的期望
为了求f,再设辅助数组g表示和的期望
那么转移显然,时间n^2

Code

我是个バカ我将中间运算过程记录成了分数实际上直接用逆元即可

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,b,a) for(int i=b;i>=a;i--)using namespace std;typedef long long ll;const int N=2010;const ll mo=998244353;int n;ll p[N];struct frac{    ll x,y;    frac(){x=0,y=1;}}q,w,f[N][N],g[N][N];ll gcd(ll x,ll y){    if(x%y==0) return y;    else return gcd(y,x%y);}frac make(ll a,ll b){    frac t;t.x=a,t.y=b;    return t;}frac add(frac a,frac b){    frac c;    c.y=a.y*b.y%mo,c.x=(a.x*b.y%mo+a.y*b.x%mo)%mo;    return c;}frac add(frac a,ll b){    frac c=make(b,1);    return add(a,c);}frac mul(frac a,frac b){    frac c;    c.x=a.x*b.x%mo,c.y=a.y*b.y%mo;    return c;}frac mul(ll k,frac b){    frac a=make(k,1);    return mul(a,b);}void exgcd(ll a,ll b,ll &x,ll &y){    if(!b)    {        x=1,y=0;        return;    }    ll x1,y1;    exgcd(b,a%b,x1,y1);    x=y1,y=x1-a/b*y1;}ll ny(ll a,ll b){    ll x,y;    exgcd(b,mo,x,y);    x=(x%mo+mo)%mo;    return a*x%mo;}int main(){    freopen("sequence.in","r",stdin);    freopen("sequence.out","w",stdout);    scanf("%d",&n);    fo(i,1,n) scanf("%lld",&p[i]);    fo(i,0,n) f[n][i].x=i*i,g[n][i].x=i,f[n][i].y=g[n][i].y=1;    fd(i,n-1,0)    {        q.x=p[i+1],q.y=100;        w.x=100-p[i+1],w.y=100;        fo(j,0,i)        {            frac x=add(g[i+1][0],j);            g[i][j]=mul(w,x);            x=add(g[i+1][j+1],j);            g[i][j]=add(g[i][j],mul(q,x));            x=add(mul(2*j,g[i+1][0]),j*j);            f[i][j]=mul(w,add(f[i+1][0],x));            x=add(mul(2*j,g[i+1][j+1]),j*j);            f[i][j]=add(f[i][j],mul(q,add(f[i+1][j+1],x)));        }    }    printf("%lld",ny(f[0][0].x,f[0][0].y));    return 0;}
0 0
原创粉丝点击