zoukankan      html  css  js  c++  java
  • LOJ#3045. 「ZJOI2019」开关

    传送门

    什么神仙题……

    这里是生成函数的做法,似乎还有(FWT)的做法 这里

    (P=sum p_i)

    对于第(i)个位置,考虑它在(n)次之后合法的概率,设其指数生成函数为(F_i(x))

    [egin{aligned} F_i(x) &=sum_{jmod 2=s_i}left(p_iover P ight)^j{x^jover j!}\ &={e^{p_ixover P}+(-1)^{s_i}e^{-p_ixover P}over 2}\ end{aligned} ]

    所以总的概率的(EGF)

    [egin{aligned} F(x)=prod_{i=1}^n {e^{p_ixover P}+(-1)^{s_i}e^{-p_ixover P}over 2} end{aligned} ]

    然而这里有可能在走完(n)步之前就到达了终止状态,这种情况可以认为是第一次到达终止状态后,走了若干个环又回到了终止状态

    我们考虑走了(n)步回到出发点的概率

    [egin{aligned} G(x)=prod_{i=1}^n {e^{p_ixover P}+e^{-p_ixover P}over 2} end{aligned} ]

    (H(x))表示答案的生成函数,令这三个函数的(OGF)分别为(f,g,h),有

    [egin{aligned} h(x)g(x)=f(x)\ h(x)={f(x)over g(x)} end{aligned} ]

    由于(h(x))是概率生成函数,所以答案就是(h'(1))

    由于

    [egin{aligned} h'(x)={f'(x)g(x)-g'(x)f(x)over g^2(x)} end{aligned} ]

    我们把(F(x))写成如下形式

    [egin{aligned} F(x)=sum_{i=-P}^P a_ie^{ixover P} end{aligned} ]

    那么对应的(f(x))就是

    [egin{aligned} f(x)=sum_{i=-P}^P a_i{1over 1-{ixover P}} end{aligned} ]

    然而我们发现当(x=1)(f(x))(g(x))不收敛(当(i=P)时后面分数形如({1over 0})),所以我们需要把(f(x))(g(x))同时乘上(prod_{i=1}^n left(1-{ixover P} ight)),这样并不影响答案。此时(f(x))

    [egin{aligned} f(x)=sum_{i=-P}^P a_iprod_{j eq i}left({1-{jxover P}} ight) end{aligned} ]

    (x=1)时,后面(j=P)可以导致后面为(0),所以有

    [egin{aligned} f(1)=a_Pprod_{j eq P}left({1-{jxover P}} ight) end{aligned} ]

    而对于(f'(x)),由于有

    [egin{aligned} left(prod_i (1+a_ix) ight)'=sum_i a_iprod_{j eq i} (1+a_jx) end{aligned} ]

    我们把(f'(x))分成两部分计算,一部分是(i eq P)的,有

    [egin{aligned} A(x)=sum_{i eq P}a_isum_{k eq i}left(-kover P ight)prod_{j eq i,j eq k}left(1-{jxover P} ight) end{aligned} ]

    而当(x=1)(k eq P)时,后面是(0),所以

    [egin{aligned} A(1)=-sum_{i eq P}a_iprod_{j eq i,j eq P}left(1-{jover P} ight) end{aligned} ]

    而后面(i=P)的部分,有

    [egin{aligned} B(1)=a_Psum_{i eq P}left(-{iover P} ight)prod_{j eq i,j eq P}left(1-{jover P} ight) end{aligned} ]

    所以

    [egin{aligned} f'(1) &=A(1)+B(1)\ &=-prod_{i eq P}left(1-frac{i}{P} ight)left(sum_{j eq P}frac{a_j}{1-frac{j}{P}}+a_Psum_{j eq P}frac{frac{j}{P}}{1-frac{j}{P}} ight) end{aligned} ]

    (g'(x))也类似,可以直接代入了

    据说还可以继续化简,然而后面我真的看不懂了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int P=998244353,inv2=(P+1)>>1;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int inc(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=5e4+5;
    int f[N<<1],g[N<<1],tmp[N<<1],s[N],p[N],n,res,sum;
    inline int calc(int *f){
    	R int res=1,ism=ksm(sum,P-2);
    	fp(i,-sum,sum-1){
    		R int iv=mul(inc(i,P),ism);
    		res=mul(res,P+1-iv);
    	}
    	return mul(res,f[sum+N]);
    }
    inline int dir(int *f){
    	R int res=1,ret=0,ism=ksm(sum,P-2);
    	fp(i,-sum,sum-1){
    		R int iv=mul(inc(i,P),ism);
    		res=mul(res,P+1-iv);
    		upd(ret,mul(ksm(P+1-iv,P-2),inc(f[i+N],mul(f[sum+N],iv))));
    	}
    	return inc(0,P-mul(res,ret));
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d",&s[i]);
    	fp(i,1,n)scanf("%d",&p[i]);
    	f[N]=g[N]=1;
    	fp(i,1,n){
    		R int v=p[i];
    		sum+=v;
    		fp(j,-sum,sum)tmp[j+N]=0;
    		R int c1=inv2,c2=s[i]?P-inv2:inv2;
    		fp(j,-sum+v,sum)upd(tmp[j+N],mul(c1,f[j+N-v]));
    		fd(j,sum-v,-sum)upd(tmp[j+N],mul(c2,f[j+N+v]));
    		fp(j,-sum,sum)f[j+N]=tmp[j+N],tmp[j+N]=0;
    		fp(j,-sum+v,sum)upd(tmp[j+N],mul(c1,g[j+N-v]));
    		fd(j,sum-v,-sum)upd(tmp[j+N],mul(c1,g[j+N+v]));
    		fp(j,-sum,sum)g[j+N]=tmp[j+N];
    	}
    	R int res=calc(g);
    	res=ksm(res,P-2),res=mul(res,res);
    	res=mul(res,inc(mul(dir(f),calc(g)),P-mul(dir(g),calc(f))));
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    Shodan在渗透测试及漏洞挖掘中的一些用法
    QUdpSocket 简单用法
    用QT操作数据库(本周学的)
    Qt使用UDp通信、套接字socket的成员函数bind()的作用
    ppm的含义
    数字的补数
    两数之和
    C++中的最大整数最小整数
    如何使用dockerfile将jar包生成镜像
    python3解决 json.dumps中文乱码
  • 原文地址:https://www.cnblogs.com/yuanquming/p/12056239.html
Copyright © 2011-2022 走看看