1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include<bits/stdc++.h> #define Tp template<typename Ty> #define Ts template<typename Ty,typename... Ar> #define Reg register #define RI Reg int #define Con const #define CI Con int& #define I inline #define W while #define N 100 #define M 400 #define X 998244353 #define Gmax(x,y) (x<(y)&&(x=(y))) #define Inc(x,y) ((x+=(y))>=X&&(x-=X)) #define Qinv(x) Qpow(x,X-2) using namespace std; int n,m,a[N+5],Fac[M+5],Inv[M+5]; I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;} class HuAutomation { private: #define SZ 2092 #define C(x,y) (1LL*Fac[x]*Inv[y]%X*Inv[(x)-(y)]%X) #define Pos(x) (p.count(x)?p[x]:(O[p[x]=++tot]=x,tot)) #define Expend(x) for(j=0;j^5;++j) O[x].S[j]=Pos(O[x]+j); class Mat { private: #define CM Con Mat& #define Rp for(RI i=0,j;i^3;++i) for(j=0;j^3;++j) #define S (i+j+k) int f[3][3]; public: I Mat() {Rp f[i][j]=-1;}I int* operator [] (CI x) {return f[x];} I bool operator != (Mat o) Con {Rp if(f[i][j]^o[i][j]) return 1;return 0;} I bool operator < (Mat o) Con {Rp if(f[i][j]^o[i][j]) return f[i][j]<o[i][j];} I bool Check() Con {Rp if(f[i][j]>3) return 1;return 0;} I void F5(Mat o,CI t) { Rp if(~o[i][j]) for(RI k=0;k^3&&S<=t;++k) Gmax(f[j][k],min(i+o[i][j]+(t-S)/3,4)); } #undef S }; struct node { int t,S[5];Mat P[2];I node() {t=S[0]=S[1]=S[2]=S[3]=S[4]=0,P[0]=P[1]=Mat();} I bool operator < (Con node& o) Con { return t^o.t?t<o.t:(P[0]!=o.P[0]?P[0]<o.P[0]:(P[1]!=o.P[1]?P[1]<o.P[1]:0)); } I node operator + (CI x) Con { if(IsHu()) return Hu();node res; res.P[0].F5(P[0],x),res.P[1].F5(P[1],x),x>1&&(res.P[1].F5(P[0],x-2),0), res.t=t+(x>1),res.IsHu()&&(res=Hu(),0);return res; } I bool IsHu() Con {return !~t||t>=7||P[1].Check();} I node Hu() Con {node x;return x.t=-1,x;} }O[SZ+5];map<node,int> p; I node Begin() {node x;return x.P[0][0][0]=0,x;} I node Hu() {node x;return x.t=-1,x;} public: int tot,f[N+5][M+5][SZ+5]; I void Build() { RI i,j;p[O[1]=Begin()]=1,p[O[2]=Hu()]=tot=2; Expend(1);for(i=3;i<=tot;++i) Expend(i); } I void DP() { for(RI i=f[0][0][1]=1,j,k,t;i<=n;++i) for(j=m;~j;--j) for(k=1;k<=tot;++k) if(f[i-1][j][k]) for(t=0;t<=4-a[i];++t) Inc(f[i][j+t][O[k].S[a[i]+t]],1LL*f[i-1][j][k]*C(4-a[i],t)%X); } }H; I void CInit(CI x) { RI i;for(Fac[0]=i=1;i<=x;++i) Fac[i]=1LL*Fac[i-1]*i%X; for(Inv[x]=Qinv(Fac[x]),i=x-1;~i;--i) Inv[i]=1LL*Inv[i+1]*(i+1)%X; } #define Calc(x,y) Inc(ans,1LL*H.f[n][x][y]*Fac[i]%X*Fac[m-i]%X) int main() { RI i,j,x,y,ans=0;for(H.Build(),scanf("%d",&n),i=1;i<=13;++i) scanf("%d%d",&x,&y),++a[x]; for(m=(n<<2)-13,CInit(m),H.DP(),i=1;i<=m;++i) for(Calc(i,1),j=3;j<=H.tot;++j) Calc(i,j); return printf("%lld",1LL*ans*Inv[m]%X+1),0; }
|