传送门
目前知道推导原理不同的做法有两种,另一种是基于集合的FWT变换解一个集合幂级数:here
题解:
设 p i p_i pi表示一次操作中选择了第 i i i个开关的概率。
首先设 F ( x ) F(x) F(x)表示操作了 i i i次之后的状态是开门状态的概率的 E G F EGF EGF,注意我们并不要求这个时刻是第一次达到开门状态,考虑单位根反演,得到:
F ( x ) = ∏ i = 1 n e p i x + ( − 1 ) s i e − p i x 2 F(x)=\prod_{i=1}^{n}\frac{e^{p_ix}+(-1)^{s_i}e^{-p_ix}}{2} F(x)=i=1∏n2epix+(−1)sie−pix
设 G ( x ) G(x) G(x)表示操作了 i i i次之后回到原状态的概率的 E G F EGF EGF,同样,我们不考虑中间是否已经达到过合法状态,显然有 G ( x ) = ∏ i = 1 n e p i x + e − p i x 2 G(x)=\prod_{i=1}^n\frac{e^{p_ix}+e^{-p_ix}}{2} G(x)=i=1∏n2epix+e−pix
设 f , g f,g f,g分别是 F , G F,G F,G的 O G F OGF OGF,设 h h h是第一次到达开门状态操作了 i i i次的概率,显然答案就是 h ′ ( 1 ) h'(1) h′(1)。
枚举过程中第一次到达开门状态的概率,我们得到 h ⋅ g = f h\cdot g=f h⋅g=f,即 h = f / g h=f/g h=f/g,那么 h ′ = f ′ g − g ′ f g 2 h'=\frac{f'g-g'f}{g^2} h′=g2f′g−g′f
考虑 E G F EGF EGF转 O G F OGF OGF,我们知道对于同一个数列的 E G F EGF EGF和 O G F OGF OGF,有 f ( x ) = ∫ F ( x t ) e − t d t f(x)=\int F(xt)e^{-t}\mathrm{d}t f(x)=∫F(xt)e−tdt
对于这道题我们尝试把 F F F写成这种形式: F ( x ) = ∑ − 1 ≤ i ≤ 1 a i e i x F(x)=\sum_{-1\leq i\leq 1}a_ie^{ix} F(x)=∑−1≤i≤1aieix,注意这里 i i i是一个实数,这里显然只有有限个 a i a_i ai非 0 0 0。则 f = ∑ − 1 ≤ i ≤ 1 a i 1 − i x f=\sum_{-1\leq i\leq 1}\frac{a_i}{1-ix} f=∑−1≤i≤11−ixai,同理设 g = ∑ − 1 ≤ i ≤ i b i 1 − i x g=\sum_{-1\leq i\leq i}\frac{b_i}{1-ix} g=∑−1≤i≤i1−ixbi,我们可以背包算 a , b a,b a,b。
考虑 h ′ = f ′ g − g ′ f g 2 h'=\frac{f'g-g'f}{g^2} h′=g2f′g−g′f,发现上下在 x = 1 x=1 x=1处不收敛很方,那么我们用 h = f ( 1 − x ) g ( 1 − x ) h=\frac{f(1-x)}{g(1-x)} h=g(1−x)f(1−x)来推导试一试,注意一下由于 f , g f,g f,g是各种的情况下概率的生成函数,所以 f ( 1 ) = g ( 1 ) = 1 f(1)=g(1)=1 f(1)=g(1)=1,可以得到 h ′ = ( f ( 1 − x ) ) ′ − ( g ( 1 − x ) ) ′ b 1 h'=\frac{(f(1-x))'-(g(1-x))'}{b_1} h′=b1(f(1−x))′−(g(1−x))′
稍微推导一下知道一定有 b 1 = 1 2 n b_1=\frac{1}{2^n} b1=2n1,然后我们考虑 f ( 1 − x ) f(1-x) f(1−x)的每一项,显然 a 1 1 − x ( 1 − x ) \frac{a_1}{1-x}(1-x) 1−xa1(1−x)项求导为 0 0 0,剩下的项考虑 ( 1 − x 1 − i x ) ′ ∣ x = 1 = 1 i − 1 (\frac{1-x}{1-ix})'|_{x=1}=\frac{1}{i-1} (1−ix1−x)′∣x=1=i−11
然后就可以做了,注意到背包出来值非零的位置的奇偶性相同,可以优化一下。
但是你说我要是没有想到上下乘上一个
1
−
x
1-x
1−x,或者我并不是很会推微积分怎么办,拿草稿纸推还被rqy给Diss了
考虑对于 f , g f,g f,g的表达式暴力通分,得到 f ( x ) = A ( x ) B ( x ) , g ( x ) = C ( x ) D ( x ) f(x)=\frac{A(x)}{B(x)},g(x)=\frac{C(x)}{D(x)} f(x)=B(x)A(x),g(x)=D(x)C(x)显然分母 B ( x ) , D ( x ) B(x),D(x) B(x),D(x)是相同的,所以我们要求的是 ( A ( 1 ) C ( 1 ) ) ′ = A ( 1 ) ′ C ( 1 ) − C ( 1 ) ′ A ( 1 ) C ( 1 ) 2 (\frac{A(1)}{C(1)})'=\frac{A(1)'C(1)-C(1)'A(1)}{C(1)^2} (C(1)A(1))′=C(1)2A(1)′C(1)−C(1)′A(1)
好了现在全部收敛了,维护一下 ( 1 − i x ) (1-ix) (1−ix)的前缀后缀积就可以做了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
cs int mod=998244353;
inline int add(int a,int b){a+=b-mod;return a+(a>>31&mod);}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
cs int N=1e2+7,M=5e4+7;
int n;
int inv[M];
int a[M],b[M],P;
inline int der1(int *f){
int ans=0;
for(int re i=0;i<P;++i)Inc(ans,mul(mul(mod>>1,inv[P-i]),f[i]));
return ans;
}
int s[N],p[N];
int main(){
#ifdef zxyoi
freopen("button.in","r",stdin);
#endif
scanf("%d",&n);a[0]=b[0]=1;
for(int re i=1;i<=n;++i)scanf("%d",s+i);
for(int re i=1;i<=n;++i)scanf("%d",p+i);
for(int re i=1;i<=n;++i){
int p=::p[i],s=::s[i];P+=p;
if(s==1){
for(int re j=P;j>=p;--j)a[j]=dec(a[j-p],a[j]);
for(int re j=p-1;~j;--j)a[j]=a[j]?mod-a[j]:0;
}else for(int re j=P;j>=p;--j)Inc(a[j],a[j-p]);
for(int re j=P;j>=p;--j)Inc(b[j],b[j-p]);
}
inv[1]=1;
for(int re i=2;i<=P;++i)inv[i]=mul(mod-mod/i,inv[mod%i]);
std::cout<<mul(P,dec(der1(a),der1(b)))<<"\n";
return 0;
}