谢谢栋栋教我这题qaq
因为完全按照他的方法做的所以题解和他的可能会长得很像qaq
先画一下柿子
a
n
s
=
E
×
a
l
l
=
a
l
l
∑
(
a
i
−
a
v
e
)
2
=
a
l
l
∑
(
a
i
2
−
2
a
i
×
a
v
e
+
a
v
e
2
)
ans=E×all=all\sum(a_i-ave)^2=all\sum(a_i^2-2a_i×ave+ave^2)
ans=E×all=all∑(ai−ave)2=all∑(ai2−2ai×ave+ave2)
a
v
e
=
∑
a
i
a
l
l
ave=\dfrac{\sum ai}{all}
ave=all∑ai
a
n
s
=
a
l
l
∑
a
i
2
−
(
∑
a
i
)
2
ans=all\sum a_i^2-(\sum a_i)^2
ans=all∑ai2−(∑ai)2
我们设
w
=
w
1
+
w
2
+
w
3
+
w
4
w=w1+w2+w3+w4
w=w1+w2+w3+w4,
d
=
∑
a
i
d=\sum a_i
d=∑ai,
d
2
=
∑
a
i
2
d_2=\sum a_i^2
d2=∑ai2
则
a
n
s
=
a
l
l
×
d
2
−
d
2
ans=all×d_2-d^2
ans=all×d2−d2,其中
a
l
l
=
w
n
all=w^n
all=wn,考虑怎么求
d
,
d
2
d,d_2
d,d2
我们将四个方向看作四个向量,一开始在(0,0),走到(x,y)相当于向量和为(x,y)
以下将 “ 不存在一个
j
(
j
>
0
)
j(j>0)
j(j>0)满足前
j
j
j个向量和为
(
x
,
y
)
(x,y)
(x,y) ” 简称为不存在前缀
(
x
,
y
)
(x,y)
(x,y),后缀同理
设
W
[
i
]
[
x
]
[
y
]
W[i][x][y]
W[i][x][y]表示走了
i
i
i步,走到
(
x
,
y
)
(x,y)
(x,y)的方案数
设
g
[
i
]
g[i]
g[i]表示走了
i
i
i步,不存在前缀
(
0
,
0
)
(0,0)
(0,0)的方案数(同时也是不存在后缀
(
0
,
0
)
(0,0)
(0,0)的方案数)
g
[
i
]
=
w
i
−
∑
j
W
[
j
]
[
0
]
[
0
]
×
g
[
i
−
j
]
g[i]=w^i-\sum_jW[j][0][0]×g[i-j]
g[i]=wi−∑jW[j][0][0]×g[i−j]
那么
d
d
d就很容易计算了,我们分开考虑每个格子的贡献,有
d
=
∑
i
g
[
i
]
×
w
n
−
i
d=\sum_ig[i]×w^{n-i}
d=∑ig[i]×wn−i
对于 d 2 d_2 d2,我们考虑像管道取珠那样转化平方贡献的方法计算他
设
R
[
i
]
[
x
]
[
y
]
R[i][x][y]
R[i][x][y]表示走了
i
i
i步,和为
(
x
,
y
)
(x,y)
(x,y),不存在前缀
(
0
,
0
)
(0,0)
(0,0)
有
R
[
i
]
[
x
]
[
y
]
=
W
[
i
]
[
x
]
[
y
]
−
∑
j
W
[
j
]
[
0
]
[
0
]
×
R
[
i
−
j
]
[
x
]
[
y
]
R[i][x][y]=W[i][x][y]-\sum_jW[j][0][0]×R[i-j][x][y]
R[i][x][y]=W[i][x][y]−∑jW[j][0][0]×R[i−j][x][y]
设
S
[
i
]
[
x
]
[
y
]
S[i][x][y]
S[i][x][y]表示走了
i
i
i步,和为
(
0
,
0
)
(0,0)
(0,0),存在前缀
(
x
,
y
)
(x,y)
(x,y)
有
S
[
i
]
[
x
]
[
y
]
=
∑
j
W
[
j
]
[
x
]
[
y
]
×
R
[
i
−
j
]
[
−
x
]
[
−
y
]
S[i][x][y]=\sum_jW[j][x][y]×R[i-j][-x][-y]
S[i][x][y]=∑jW[j][x][y]×R[i−j][−x][−y]
设
F
[
i
]
[
x
]
[
y
]
F[i][x][y]
F[i][x][y]表示
对于所有长度为
i
i
i的向量序列,其前
j
(
j
<
i
)
j(j<i)
j(j<i)个向量和为
(
a
,
b
)
(a,b)
(a,b),后
i
−
j
i-j
i−j个向量和为
(
x
,
y
)
(x,y)
(x,y)
且第
j
j
j步第一次到达
(
a
,
b
)
(a,b)
(a,b)(不存在后缀
(
0
,
0
)
(0,0)
(0,0)),第
i
i
i步第一次到达
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y)
这样的
j
j
j的个数之和
其实就是将一条路径覆盖的 a i a_i ai个格子,按照第一次到达的顺序排序后,从左到右取出每个格子和后面的所有格子匹配贡献到 a i 2 a_i^2 ai2里,最后要乘2算上倒序的匹配,再加上 a i a_i ai表示自己和自己匹配
F [ i ] [ x ] [ y ] F[i][x][y] F[i][x][y]的dp式分三部分
F
[
i
]
[
x
]
[
y
]
+
=
∑
j
g
[
j
]
×
W
[
i
−
j
]
[
x
]
[
y
]
F[i][x][y]+=\sum_jg[j]×W[i-j][x][y]
F[i][x][y]+=∑jg[j]×W[i−j][x][y]
因为
g
[
j
]
g[j]
g[j]也能表示不存在后缀
(
0
,
0
)
(0,0)
(0,0)即第一次到达某个点
(
a
,
b
)
(a,b)
(a,b),然后剩下
i
−
j
i-j
i−j步和为
(
x
,
y
)
(x,y)
(x,y),所有合法方案他一定能算进去,考虑他会算到哪些不合法的方案
会算到不合法主要是因为我们不能保证第
i
i
i步时第一次到达
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y),他可能在第
j
j
j步前就到达过,或者在第
j
j
j步后第
i
i
i步前到达过
F
[
i
]
[
x
]
[
y
]
−
=
∑
j
g
[
j
]
×
S
[
i
−
j
]
[
−
x
]
[
−
y
]
F[i][x][y]-=\sum_jg[j]×S[i-j][-x][-y]
F[i][x][y]−=∑jg[j]×S[i−j][−x][−y]
这里减去的是第
j
j
j步前到达
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y)后走回
(
a
,
b
)
(a,b)
(a,b)再回到
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y)的方案,但他还会减去第一次到
(
a
,
b
)
(a,b)
(a,b)后到
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y)再绕回
(
a
,
b
)
(a,b)
(a,b)最后又回到
(
a
+
x
,
b
+
y
)
(a+x,b+y)
(a+x,b+y)的方案,因为我们第三部分会再减一次这种情况,所以我们要在第三部分把这些方案加回来(避免重复减同一种情况)
F
[
i
]
[
x
]
[
y
]
−
=
∑
j
F
[
j
]
[
x
]
[
y
]
×
(
W
[
i
−
j
]
[
0
]
[
0
]
−
S
[
i
−
j
]
[
−
x
]
[
−
y
]
)
F[i][x][y]-=\sum_jF[j][x][y]×(W[i-j][0][0]-S[i-j][-x][-y])
F[i][x][y]−=∑jF[j][x][y]×(W[i−j][0][0]−S[i−j][−x][−y])
这里的
S
[
i
−
j
]
[
−
x
]
[
−
y
]
S[i-j][-x][-y]
S[i−j][−x][−y]就是我们在第二部分多减的东西
然后 d 2 = ( ∑ i , x , y F [ i ] [ x ] [ y ] × w n − i ) × 2 + d d_2=(\sum_{i,x,y}F[i][x][y]×w^{n-i})×2+d d2=(∑i,x,yF[i][x][y]×wn−i)×2+d
然后这题就做完啦(撒花)
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define W(i,x,y) W[x+base][y+base][i]
#define R(i,x,y) R[x+base][y+base][i]
#define S(i,x,y) S[x+base][y+base][i]
#define F(i,x,y) F[x+base][y+base][i]
using namespace std;
const int maxn = 210;
const int mod = 998244353;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
const int base = 105;
inline void add(int &a,const int &b){a+=b;if(a>=mod)a-=mod;}
inline void dec(int &a,const int &b){a-=b;if(a<0)a+=mod;}
int n,w[4],pw[maxn];
int W[maxn][maxn][maxn],g[maxn],R[maxn][maxn][maxn],S[maxn][maxn][maxn],F[maxn][maxn][maxn];
int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);
scanf("%d",&n);
scanf("%d%d%d%d",&w[0],&w[2],&w[1],&w[3]);
pw[0]=1,pw[1]=w[0]+w[1]+w[2]+w[3]; for(int i=2;i<=n;i++) pw[i]=(ll)pw[i-1]*pw[1]%mod;
W(0,0,0)=1;
for(int i=1;i<=n;i++)
{
for(int x=-i;x<=i;x++) for(int y=-i+abs(x);y<=i-abs(x);y++)
for(int k=0;k<4;k++) add(W(i,x,y),(ll)W(i-1,x+dx[k],y+dy[k])*w[(k+2)&3]%mod);
}
for(int i=0;i<=n;i++)
{
g[i]=pw[i];
for(int j=1;j<=i;j++) dec(g[i],(ll)W(j,0,0)*g[i-j]%mod);
}
for(int i=0;i<=n;i++)
{
for(int x=-i;x<=i;x++) for(int y=-i+abs(x);y<=i-abs(x);y++)
{
R(i,x,y)=W(i,x,y);
for(int j=1;j<i;j++) dec(R(i,x,y),(ll)W(j,0,0)*R(i-j,x,y)%mod);
}
}
for(int i=0;i<=n;i++)
{
for(int x=-i;x<=i;x++) for(int y=-i+abs(x);y<=i-abs(x);y++)
{
for(int j=1;j<i;j++) add(S(i,x,y),(ll)W(j,x,y)*R(i-j,-x,-y)%mod);
}
}
for(int i=1;i<=n;i++)
{
for(int x=-i;x<=i;x++) for(int y=-i+abs(x);y<=i-abs(x);y++)
{
for(int j=0;j<i;j++) add(F(i,x,y),(ll)g[j]*W(i-j,x,y)%mod);
for(int j=0;j<i;j++) dec(F(i,x,y),(ll)g[j]*S(i-j,-x,-y)%mod);
for(int j=0;j<i;j++) dec(F(i,x,y),(ll)F(j,x,y)*((W(i-j,0,0)-S(i-j,-x,-y)+mod)%mod)%mod);
}
}
int d=0,d2=0;
for(int i=0;i<=n;i++) add(d,(ll)g[i]*pw[n-i]%mod);
for(int i=0;i<=n;i++)
{
for(int x=-i;x<=i;x++) for(int y=-i+abs(x);y<=i-abs(x);y++) if(x||y)
add(d2,(ll)F(i,x,y)*pw[n-i]%mod);
}
add(d2,d2);
add(d2,d);
int ans=(ll)d2*pw[n]%mod; dec(ans,(ll)d*d%mod);
printf("%d\n",ans);
return 0;
}