一、题目
二、解法
考虑每个灯的生成函数,那么答案的生成函数为它们的乘积,设
P
=
∑
p
i
P=\sum p_i
P=∑pi(这里用
e
e
e不是特别严谨,因为本题不需要指数型生成函数,但是为了方便表示无穷级数,使用
e
e
e可能会更加简洁):
F
(
x
)
=
∏
i
=
1
n
e
p
i
P
x
+
(
−
1
)
s
i
e
−
p
i
P
x
2
F(x)=\prod_{i=1}^n \frac{e^{\frac{p_i}{P}x}+(-1)^{s_i}e^{-\frac{p_i}{P}x}}{2}
F(x)=i=1∏n2ePpix+(−1)sie−Ppix但是还有一个问题,就是上面的生成函数并不会在第一次满足条件是就停止,我们考虑转满一圈,也就是操作会原状态的生成函数:
G
(
x
)
=
∏
i
=
1
n
e
p
i
P
x
+
e
−
p
i
P
x
2
G(x)=\prod_{i=1}^n \frac{e^{\frac{p_i}{P}x}+e^{-\frac{p_i}{P}x}}{2}
G(x)=i=1∏n2ePpix+e−Ppix求出
F
,
G
F,G
F,G直接暴力背包,时间复杂度
O
(
n
p
)
O(np)
O(np),考虑答案的生成函数为
H
(
x
)
H(x)
H(x),则满足
h
(
x
)
g
(
x
)
=
f
(
x
)
h(x)g(x)=f(x)
h(x)g(x)=f(x)(
h
,
g
,
f
h,g,f
h,g,f为
H
,
G
,
F
H,G,F
H,G,F的普通生成函数),考虑使用闭形式来表示它们之间的转化,它们之间满足这样的转化关系:
f
(
x
)
=
∑
i
=
−
P
P
a
i
1
−
i
P
x
f(x)=\sum_{i=-P}^{P} \frac{a_i}{1-\frac{i}{P}x}
f(x)=i=−P∑P1−Pixai此时要求的答案是
h
′
(
1
)
h'(1)
h′(1),求导就是把每种概率乘上他的权值(步数),算出来就是期望,可以使用这个公式,(
1
g
(
x
)
\frac{1}{g(x)}
g(x)1的求导可以当做复合函数求导,也就是加入一个辅助函数
f
(
x
)
=
1
x
f(x)=\frac{1}{x}
f(x)=x1):
(
f
(
x
)
g
(
x
)
)
′
=
(
f
(
x
)
g
(
x
)
−
1
)
′
=
f
′
(
x
)
g
(
x
)
−
f
(
x
)
g
′
(
x
)
g
(
x
)
2
(\frac{f(x)}{g(x)})'=(f(x)g(x)^{-1})'=\frac{f'(x)g(x)-f(x)g'(x)}{g(x)^2}
(g(x)f(x))′=(f(x)g(x)−1)′=g(x)2f′(x)g(x)−f(x)g′(x)发现这样算出来的
h
h
h是不收敛的,我们把
f
,
g
f,g
f,g同乘
∏
1
−
i
p
\prod1-\frac{i}p{}
∏1−pi,现在的问题在于解决
f
(
x
)
f(x)
f(x)的导数,我们来推式子:
f
(
x
)
=
∑
a
i
∏
j
≠
i
1
−
j
p
x
f(x)=\sum a_i\prod_{j\not=i}1-\frac{j}{p}x
f(x)=∑aij=i∏1−pjx为了方便表示,我们设
g
i
(
x
)
=
a
i
∏
j
≠
i
j
p
x
,
h
i
(
x
)
=
1
−
i
p
x
g_i(x)=a_i\prod_{j\not=i}\frac{j}{p}x,h_i(x)=1-\frac{i}p{x}
gi(x)=ai∏j=ipjx,hi(x)=1−pix,我们想对
g
g
g求导:
g
i
′
(
x
)
=
a
i
∏
j
≠
i
h
j
(
x
)
′
g_i'(x)=a_i\prod_{j\not=i}h_j(x)'
gi′(x)=aij=i∏hj(x)′
g
i
′
(
x
)
=
a
i
∑
k
≠
i
(
∏
j
≠
i
,
j
≠
k
h
j
(
x
)
)
×
h
k
(
x
)
′
g_i'(x)=a_i\sum_{k\not=i}(\prod_{j\not=i,j\not=k}h_j(x))\times h_k(x)'
gi′(x)=aik=i∑(j=i,j=k∏hj(x))×hk(x)′
g
i
′
(
x
)
=
a
i
∑
k
≠
i
(
∏
j
≠
i
h
j
(
x
)
)
×
h
k
(
x
)
′
h
k
(
x
)
.
.
.
.
.
.
∗
g_i'(x)=a_i\sum_{k\not=i}(\prod_{j\not=i}h_j(x))\times \frac{h_k(x)'}{h_k(x)}......*
gi′(x)=aik=i∑(j=i∏hj(x))×hk(x)hk(x)′......∗
g
i
′
(
x
)
=
a
i
(
∏
j
≠
i
h
j
(
x
)
)
∑
k
≠
i
h
k
(
x
)
′
h
k
(
x
)
g_i'(x)=a_i(\prod_{j\not=i}h_j(x))\sum_{k\not=i}\frac{h_k(x)'}{h_k(x)}
gi′(x)=ai(j=i∏hj(x))k=i∑hk(x)hk(x)′
g
i
′
(
x
)
=
a
i
(
∏
j
≠
i
1
−
j
p
x
)
∑
k
≠
i
−
k
p
1
−
k
p
x
g_i'(x)=a_i(\prod_{j\not=i}1-\frac{j}{p}x)\sum_{k\not=i}\frac{-\frac{k}{p}}{1-\frac{k}{p}x}
gi′(x)=ai(j=i∏1−pjx)k=i∑1−pkx−pk那么
f
′
(
x
)
f'(x)
f′(x)就算出来了,长成这样:
f
′
(
x
)
=
∑
i
a
i
(
∏
j
≠
i
1
−
j
p
x
)
∑
k
≠
i
−
k
p
1
−
k
p
x
f'(x)=\sum_ia_i(\prod_{j\not=i}1-\frac{j}{p}x)\sum_{k\not=i}\frac{-\frac{k}{p}}{1-\frac{k}{p}x}
f′(x)=i∑ai(j=i∏1−pjx)k=i∑1−pkx−pk考虑求除
f
′
(
1
)
f'(1)
f′(1)的值,可以分类讨论,由于
x
=
1
x=1
x=1是,
1
−
i
p
1-\frac{i}{p}
1−pi很特殊,我们考虑
i
i
i是否等于
p
p
p
-
i
≠
p
i\not=p
i=p,考虑到
j
j
j的枚举中会有
0
0
0这一项产生(
j
=
p
j=p
j=p时),那就都消完了?等等,看我标注了
*
号的柿子,我们为了提出相同的一项而乘上又除去了 1 − k p x 1-\frac{k}p{x} 1−pkx,所以在 k k k中产生的 − 1 0 \frac{-1}{0} 0−1必须要与 0 0 0的一项对消,产生 − 1 -1 −1,所以当 i ≠ p i\not=p i=p时, k k k只能等于 p p p,这样我们就可以对 g g g函数进行化简:
g i ′ ( x ) = − a i ∏ j ≠ i , j ≠ p 1 − j p x g_i'(x)=-a_i\prod_{j\not=i,j\not=p}1-\frac{j}p{x} gi′(x)=−aij=i,j=p∏1−pjx g i ′ ( x ) = − ∏ j ≠ p 1 − j p x × a i 1 − i p x g_i'(x)=-\prod_{j\not=p}1-\frac{j}{p}x\times\frac{a_i}{1-\frac{i}{p}x} gi′(x)=−j=p∏1−pjx×1−pixai - i = p i=p i=p,直接带推出的 f ′ ( x ) f'(x) f′(x)的柿子去算,比较简单。
分类讨论之后,我们可以知道
f
′
(
1
)
f'(1)
f′(1)的值:
f
′
(
1
)
=
−
(
∏
i
≠
p
1
−
i
p
)
(
∑
i
≠
p
a
i
1
−
i
p
+
a
p
∑
i
≠
p
i
p
1
−
i
p
)
f'(1)=-(\prod_{i\not=p}1-\frac{i}{p})(\sum_{i\not=p}\frac{a_i}{1-\frac{i}{p}}+a_p\sum_{i\not=p}\frac{\frac{i}{p}}{1-\frac{i}{p}})
f′(1)=−(i=p∏1−pi)(i=p∑1−piai+api=p∑1−pipi)知道了
f
′
(
1
)
f'(1)
f′(1)的求导之后,
g
′
(
1
)
g'(1)
g′(1)也很容易(好像和推导的重名了,写到这里才发现,请谅解),我们可以带入上面对分式求导的柿子,就可以算出答案(设
a
i
a_i
ai为
f
f
f的系数,
b
i
b_i
bi为
g
g
g的系数,容易发现
a
p
=
b
p
=
1
2
n
a_p=b_p=\frac{1}{2^n}
ap=bp=2n1):
2
n
∑
i
≠
p
b
i
−
a
i
1
−
i
p
2^n\sum_{i\not=p}\frac{b_i-a_i}{1-\frac{i}{p}}
2ni=p∑1−pibi−ai写的我要吐了,贴上简洁的代码:
#include <cstdio>
#include <cstring>
#define int long long
const int M = 50005;
const int MOD = 998244353;
int read()
{
int x=0,flag=1;
char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,sum,inv,ans,s[105],tmp[2*M],f[2*M],g[2*M];
int qkpow(int a,int b)
{
int r=1;
while(b>0)
{
if(b&1) r=r*a%MOD;
a=a*a%MOD;
b>>=1;
}
return r;
}
signed main()
{
n=read();
for(int i=1; i<=n; i++)
s[i]=read();
inv=qkpow(2,MOD-2);
f[M]=g[M]=1;
for(int i=1; i<=n; i++)
{
int x=read();
sum+=x;
memset(tmp,0,sizeof tmp);
for(int j=-sum; j+x<=sum; j++) tmp[j+x+M]=(tmp[j+x+M]+inv*f[j+M])%MOD;
for(int j=-sum+x; j<=sum; j++) tmp[j-x+M]=(tmp[j-x+M]+(s[i]?MOD-inv:inv)*f[j+M])%MOD;
memcpy(f,tmp,sizeof tmp);
//
memset(tmp,0,sizeof tmp);
for(int j=-sum; j+x<=sum; j++) tmp[j+x+M]=(tmp[j+x+M]+inv*g[j+M])%MOD;
for(int j=-sum+x; j<=sum; j++) tmp[j-x+M]=(tmp[j-x+M]+inv*g[j+M])%MOD;
memcpy(g,tmp,sizeof tmp);
}
for(int i=-sum; i<=sum; i++) ans=(ans+(g[i+M]-f[i+M]+MOD)*qkpow(sum-i,MOD-2))%MOD;
printf("%lld\n",ans*sum%MOD*qkpow(2,n)%MOD);
}