谢谢栋栋教我这题qaq
因为完全按照他的方法做的所以题解和他的可能会长得很像qaq
先画一下柿子
我们设
,
,
则
,其中
,考虑怎么求
我们将四个方向看作四个向量,一开始在(0,0),走到(x,y)相当于向量和为(x,y)
以下将 “ 不存在一个
满足前
个向量和为
” 简称为不存在前缀
,后缀同理
设
表示走了
步,走到
的方案数
设
表示走了
步,不存在前缀
的方案数(同时也是不存在后缀
的方案数)
那么
就很容易计算了,我们分开考虑每个格子的贡献,有
对于 ,我们考虑像管道取珠那样转化平方贡献的方法计算他
设
表示走了
步,和为
,不存在前缀
有
设
表示走了
步,和为
,存在前缀
有
设
表示
对于所有长度为
的向量序列,其前
个向量和为
,后
个向量和为
且第
步第一次到达
(不存在后缀
),第
步第一次到达
这样的
的个数之和
其实就是将一条路径覆盖的 个格子,按照第一次到达的顺序排序后,从左到右取出每个格子和后面的所有格子匹配贡献到 里,最后要乘2算上倒序的匹配,再加上 表示自己和自己匹配
的dp式分三部分
因为
也能表示不存在后缀
即第一次到达某个点
,然后剩下
步和为
,所有合法方案他一定能算进去,考虑他会算到哪些不合法的方案
会算到不合法主要是因为我们不能保证第
步时第一次到达
,他可能在第
步前就到达过,或者在第
步后第
步前到达过
这里减去的是第
步前到达
后走回
再回到
的方案,但他还会减去第一次到
后到
再绕回
最后又回到
的方案,因为我们第一部分并不会算入这种情况,我们要在第三部分把这些方案加回来
这里的
就是我们在第二部分多减的东西
然后
然后这题就做完啦(撒花)
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;
}