Problem:
座席 (Seats)
問題文
2XXX 年，世界の国は直線状に並んでいた．
N
個の国があり，
1, 2, ..., N
の番号が付けられている．
i = 1, 2, ..., N - 1
に対し，国
i
と国
i + 1
が互いに隣国である．
この年の国際情報オリンピックでは，国
i
からは
A_i
人の選手が参加する．国際情報オリンピックの技術委員のあなたは，競技での座席表を作成する担当である．競技会場が細長いため，一列に並んだ
A_1 + A_2 + ... + A_N
個の座席に選手たちを割り当てることになった．不正防止のため，同じ国の選手や隣国の選手を隣り合う席に割り当ててはならない．
選手たちを座席に割り当てる方法は何通りあるだろうか．この数は非常に大きくなる可能性があるので，それを
10007
で割った余りを求めたい．
制約
1 ≦ N ≦ 100
1 ≦ A_i ≦ 4
(
1 ≦ i ≦ N
)
入力・出力
入力
入力は以下の形式で標準入力から与えられる．
N
A_1
A_2
...
A_N
出力
選手たちを座席に割り当てる方法の数を
10007
で割った余りを
1
行で出力せよ．
入出力例
入力例 1
4
2 1 1 1
出力例 1
4
国
1
から参加する
2
人の選手を
1
と
1'
，国
2
から参加する
1
人の選手を
2
，国
3
から参加する
1
人の選手を
3
，国
4
から参加する
1
人の選手を
4
で表すことにすると，選手たちを座席に割り当てる方法としては，以下の
4
通りの並べ方が考えられる：
1
,
3
,
1'
,
4
,
2
1'
,
3
,
1
,
4
,
2
2
,
4
,
1
,
3
,
1'
2
,
4
,
1'
,
3
,
1
入力例 2
5
1 2 3 2 1
出力例 2
0
この入力例では，条件を満たす座席表は存在しない．
入力例 3
6
1 2 3 3 2 1
出力例 2
4754
この入力例では，選手たちを座席に割り当てる方法は
24768
通りあるため，それを
10007
で割った余りである
4754
を出力する．
情報オリンピック日本委員会作 『第 18 回日本情報オリンピック JOI 2018/2019 予選競技課題』

Submitted solutions:

code_snippet: #include <iostream>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
 //6780
struct E{
	int a,b,c,d,e;
};
struct E2{
	int p,no;
};
 
 
using namespace std;
vector<int> v[6];
map<vector<int>,int> toE2[5];
map<E,int> ep;
int m= 10007;
//int m=1000000007;
int dp[2][410][9][9][4];
int cs[101];
int cs2[101];
int ps[5]={1,1,2,6,24};
int ps2[5]={0,0,1,2,3};
int nowx;
int nextx;
int nowP;
int data4[11][2][4]={
	{{4,0,0,0},{4,24,0,0}},
	{{2,2,0,0},{4,12,0,0}},
	{{1,3,0,0},{4,24,0,0}},
	{{1,1,2,0},{4,12,0,0}},
	{{1,1,1,1},{4,1,0,0}},
	{{3,0,0,0},{3,24,0,0}},
	{{1,2,0,0},{3,24,0,0}},
	{{1,1,1,0},{3,4,0,0}},
	{{2,0,0,0},{2,12,0,0}},
	{{1,1,0,0},{2,6,0,0}},
	{{1,0,0,0},{1,4,0,0}}};
int data3[7][2][4]={
	{{3,0,0,0},{3,6,0,0}},
	{{2,1,0,0},{3,6,0,0}},
	{{1,2,0,0},{3,6,0,0}},
	{{1,1,1,0},{3,1,0,0}},
	{{2,0,0,0},{2,6,0,0}},
	{{1,1,0,0},{2,3,0,0}},
	{{1,0,0,0},{1,3,0,0}}
	};
int data2[3][2][4]={
	{{2,0,0,0},{2,2,0,0}},
	{{1,1,0,0},{1,1,0,0}},
	{{1,0,0,0},{1,2,0,0}},
	};
 
int cs3[7];
int cs4[102];
 
void f(int no,int n,int nots,int olds,int nows,int nowsA,int nows2,int nexts,int nextsA,int nexts2,int hasi,int hasi2,int p1){
	
	int k1;
	if(cs3[no]==-1){
		cs3[no]=n;
		k1=-1;
	}else{
		k1=cs3[no];
	}
	int s=1;
	if(v[no].size()>0)s=v[no][v[no].size()-1];
	if(no==0){
		//古いところで隙間がないところ
		f(1,n,nots,olds,nows,nowsA,nows2,nexts,nextsA,nexts2,hasi,hasi2,(p1*toE2[cs3[no]][v[no]])%m);
		if(nots>0){
			for(int i=s;i<=n;i++){
				v[no].push_back(i);
				f(no,n-i,nots-1,olds,nows,nowsA,nows2,nexts+2,nextsA,nexts2+ps2[i],hasi,hasi2,(p1*nots)%m);
				v[no].pop_back();
			}
		}
	}else if(no==1){
		//古いところで隙間があるところ
		f(2,n,nots,olds,nows,nowsA,nows2,nexts,nextsA,nexts2,hasi,hasi2,(p1*toE2[cs3[no]][v[no]])%m);
		if(olds>0){
			for(int i=s;i<=n;i++){
				v[no].push_back(i);
				f(no,n-i,nots,olds-1,nows,nowsA,nows2,nexts+2,nextsA,nexts2+ps2[i],hasi,hasi2,(p1*olds)%m);
				v[no].pop_back();
			}
		}
	}else if(no==2){
		f(3,n,nots,olds,nows,nowsA,nows2,nexts,nextsA,nexts2,hasi,hasi2,(p1*toE2[cs3[no]][v[no]])%m);
		//片方に１小さい数があるところ
		if(nows>0){
			for(int i=s;i<=n;i++){
				v[no].push_back(i);
				f(no,n-i,nots,olds,nows-1,nowsA,nows2,nexts+1,nextsA+1,nexts2+ps2[i],hasi,hasi2,(p1*nows)%m);
				v[no].pop_back();
 
			}
		}
	}else if(no==3){
		f(4,n,nots,olds,nows,nowsA,nows2,nexts,nextsA,nexts2,hasi,hasi2,(p1*toE2[cs3[no]][v[no]])%m);
		if(nowsA>0){
			for(int i=s;i<=n;i++){
				v[no].push_back(i);
				f(no,n-i,nots,olds,nows,nowsA-1,nows2,nexts+1,nextsA+1,nexts2+ps2[i],hasi,hasi2,(p1*nowsA)%m);
				v[no].pop_back();
			}
		}
	}else if(no==4){
		f(5,n,nots,olds,nows,nowsA,nows2,nexts,nextsA,nexts2,hasi,hasi2,(p1*toE2[cs3[no]][v[no]])%m);
		if(nows2>0){
			for(int i=s;i<=n;i++){
				v[no].push_back(i);
				f(no,n-i,nots,olds,nows,nowsA,nows2-1,nexts,nextsA+2,nexts2+ps2[i],hasi,hasi2,(p1*nows2)%m);
				v[no].pop_back();
			}
		}
 
	}else if(no==5){
		int olds2=olds+nows2+nowsA;
		if(olds2>210){
			return ;
		}
		if (n==0){
				int p2=1;
				int c3=0;
				//p2*=ps[c3];
				dp[nextx][olds2][nexts][nextsA][nexts2]=(dp[nextx][olds2][nexts][nextsA][nexts2]+p1)%m;
				//dp[nextx][olds2][nexts][nextsA][nexts2][0]=(dp[nextx][olds2][nexts][nextsA][nexts2][0]+p1)%m;
		}
	}
	cs3[no]=k1;
}
 
int main() {
	// your code goes here
	memset(dp,0,sizeof(dp));
 
	int n;
	cin>>n;
	int t1=0;
	for(int i=0;i<n;i++){
		cin>>cs[i];
		t1+=cs[i];
		cs2[i]=t1;
	}
	t1=0;
	for(int i=n-1;i>=0;i--){
		t1+=cs[i];
		cs4[i]=t1;
	}

	if(n<2){
		int ans=0;
		if(cs[0]==1)ans=1;
		cout<<ans<<endl;
		return 0;
	}
	for(int i=0;i<11;i++){
		vector<int> v2;
		E2 e1;
		e1.p=1;
		e1.no=0;
		toE2[0][v2]=1;
		toE2[1][v2]=1;
		toE2[2][v2]=1;
		toE2[3][v2]=1;
		toE2[4][v2]=1;
		for(int j=0;j<4;j++){
			if(data4[i][0][j]==0){
				break;
			}else{
				v2.push_back(data4[i][0][j]);
			}
		}
		toE2[4][v2]=data4[i][1][1];
	}
	for(int i=0;i<7;i++){
		vector<int> v2;
		for(int j=0;j<4;j++){
			if(data3[i][0][j]==0){
				break;
			}else{
				v2.push_back(data3[i][0][j]);
			}
		}
		toE2[3][v2]=data3[i][1][1];
	}
	for(int i=0;i<3;i++){
		vector<int> v2;
		for(int j=0;j<4;j++){
			if(data2[i][0][j]==0){
				break;
			}else{
				v2.push_back(data2[i][0][j]);
			}
		}
 
 
		E2 e2;
		e2.no=data2[i][1][0];
		e2.p=data2[i][1][1];
		toE2[2][v2]=data2[i][1][1];
	}
	vector<int> v0;
	v0.push_back(1);
	toE2[1][v0]=1;
 
	memset(cs3,-1,sizeof(cs3));
	dp[1][0][2][0][cs[0]-1]=ps[cs[0]];
 
	for(int i=1;i<n;i++){
		nowx=i%2;
		nextx=(i+1)%2;
		for(int sp1=0;sp1<9;sp1++){
		for(int sp1A=0;sp1A<9-sp1;sp1A++){
			for(int os=0;os<=min(cs4[i-1]+5,cs2[i-1]);os++){
				for(int sp2=0;sp2<4;sp2++){
				int t2=cs2[i-1]+1-sp1-os-sp1A-sp2;
				if (t2<0){
					break;
				}
					int t1=dp[nowx][os][sp1][sp1A][sp2];
					if (t1==0) continue;
					dp[nowx][os][sp1][sp1A][sp2]=0;
					f(0,cs[i],t2,os,sp1,sp1A,sp2,0,0,0,0,0,t1);
				}
			}
			}
		}
	}
	int ans=0;
	for(int sp1=0;sp1<9;sp1++){
			ans=(ans+dp[nextx][0][sp1][0][0])%m;
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 2070
memory_kb: 4192
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

long long N, A[109], S[109], dp[109][309][9][4], nr[509][509], mod = 10007;

int COUNTRY = 0, ORDINARY = 0, DANGER = 0, DANGER1 = 0, DANGER2 = 0, PLUS = 0, BASE = 0;

void init() {
	for (int i = 0; i <= 500; i++) {
		for (int j = 0; j <= 500; j++) {
			if (i == 0 || j == 0) nr[i][j] = 1;
			else nr[i][j] = (nr[i - 1][j] + nr[i][j - 1]) % mod;
		}
	}
}

int ncr(int n, int r) {
	if (n < r || r < 0) return 0;
	return nr[r][n - r];
}

void calc(int num, int danger2, int multi) {
	for (int i = 0; i <= num; i++) {
		for (int j = 0; i + j <= num; j++) {
			for (int k = 0; i + j + k <= num; k++) {
				for (int l = 0; i + j + k + l <= num; l++) {
					int m = num - i - j - k - l;

					int v1 = ncr(ORDINARY, i);
					int v2 = ncr(DANGER, j);
					int v3 = ncr(DANGER1, k);
					int v4 = ncr(DANGER2, l);
					int v5 = ncr(PLUS, m);
					int product = (((v1 * v2 % mod) * v3 % mod) * v4 % mod) * v5 % mod;
					if (product == 0) continue;

					int T1 = COUNTRY;
					int T2 = DANGER - j + (DANGER1 - k) + (DANGER2 - l);
					int T3 = k + l * 2 + m;
					int T4 = danger2;
					dp[T1][T2][T3][T4] += BASE * product * multi;
					dp[T1][T2][T3][T4] %= mod;
				}
			}
		}
	}
}

void solve(int country, int danger, int danger1, int danger2) {
	COUNTRY = country + 1;
	DANGER = danger;
	DANGER1 = danger1;
	DANGER2 = danger2;
	PLUS = 2 * A[country] - DANGER1 - 2 * DANGER2;
	ORDINARY = S[country] + 1 - DANGER - DANGER1 - DANGER2 - PLUS;
	BASE = dp[country][danger][danger1][danger2];

	if (A[country + 1] == 1) {
		calc(1, 0, 1); // (1)
	}
	if (A[country + 1] == 2) {
		calc(1, 1, 1); // (2)
		calc(2, 0, 1); // (1, 1)
	}
	if (A[country + 1] == 3) {
		calc(1, 2, 1); // (3)
		calc(2, 1, 2); // (2, 1)
		calc(3, 0, 1); // (1, 1, 1)
	}
	if (A[country + 1] == 4) {
		calc(1, 3, 1); // (4)
		calc(2, 2, 3); // (3, 1), (2, 2)
		calc(3, 1, 3); // (2, 1, 1)
		calc(4, 0, 1); // (1, 1, 1, 1)
	}
}

int checker() {
	vector<int>vec;
	for (int i = 1; i <= N; i++) {
		for (int j = 0; j < A[i]; j++) vec.push_back(i);
	}
	int cnts = 0;
	do {
		bool flag = true;
		for (int i = 0; i < vec.size() - 1; i++) {
			if (abs(vec[i] - vec[i + 1]) <= 1) flag = false;
		}
		if (flag == true) {
			/*for (int i = 0; i < N; i++) {
				if (i) cout << " "; cout << a[i];
			}
			cout << endl;*/
			cnts++;
		}
	} while (next_permutation(vec.begin(), vec.end()));
	return cnts % mod;
}

int main() {
	cin >> N; init();
	for (int i = 1; i <= N; i++) {
		cin >> A[i]; S[i] = S[i - 1] + A[i];
	}
	dp[0][0][0][0] = 1;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < 3 * N; j++) {
			for (int k = 0; k <= 8; k++) {
				for (int l = 0; l <= 3; l++) {
					if (dp[i][j][k][l] == 0) continue;
					solve(i, j, k, l);
				}
			}
		}
	}
	long long ret = dp[N][0][0][0];
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= A[i]; j++) { ret *= j; ret %= mod; }
	}
	cout << ret << endl;
	//cout << checker() << endl;
	return 0;
}
accuracy: 1
time_ms: 2110
memory_kb: 10712
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)

int MOD = 10007;
long long c[402][402], fac[5], dp[100][400][4][8];

long long C(int n, int r) {
  if (n < r || r < 0) return 0;
  return c[r][n-r];
}

int main() {
  REP(i, 402) REP(j, 402) {
    if (i == 0 || j == 0) c[i][j] = 1;
    else c[i][j] = (c[i-1][j] + c[i][j-1]) % MOD;
  }
  fac[1] = 1;
  fac[2] = 2;
  fac[3] = 6;
  fac[4] = 24;

  int n, sum = 0; cin >> n;
  vector<int> a(n); REP(i, n) cin >> a[i];
  dp[0][a[0]-1][a[0]-1][0] = fac[a[0]];
  REP(i, n-1) {
    sum += a[i];
    REP(j, sum) REP(k, min(j+1, a[i])) REP(l, min(j-k+1, (i==0?1:a[i-1]+a[i]))) {
      FOR(u, 1, a[i+1]+1) REP(w, min(k, u)+1) REP(x, min(l, u-w)+1) REP(y, min(j-k-l, u-w-x)+1) REP(z, min(2*a[i]-2*k-l, u-w-x-y)+1) {
        (dp[i+1][j+a[i+1]-u+w-y+z][a[i+1]-u][2*w+x+z] += dp[i][j][k][l] * C(a[i+1]-1, u-1) % MOD * C(k, w) % MOD * C(l, x) % MOD * C(j-k-l, y) % MOD * C(2*a[i]-2*k-l, z) % MOD * C(sum+1-j-(2*a[i]-2*k-l), u-w-x-y-z) % MOD * fac[a[i+1]] % MOD) %= MOD;
      }
    }
  }
  cout << dp[n-1][0][0][0] << '\n';
  return 0;
}
accuracy: 1
time_ms: 2720
memory_kb: 9656
final_rank: 5

code_snippet: #include <bits/stdc++.h>

//    #include <boost/multiprecision/cpp_int.hpp>
// #define int long long
 #define inf  1000000007
 #define pa pair<int,int>
 #define ll long long
 #define pal pair<double,double>
 #define ppap pair<pa,int>
  #define PI 3.14159265358979323846
  #define paa pair<int,char>
  #define  mp make_pair
  #define  pb push_back
  #define EPS (1e-10)
                                          
    int dx[8]={0,1,0,-1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x,y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	int x;
                                            	int y,z,w;
                                            	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
/*
                                            class Point{
                                            	public:
                                            	double x,y;
                                            	Point(double x=0,double y=0):x(x),y(y) {}
                                            	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
                                            	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
                                            	Point operator * (double a) {return Point(x*a,y*a);}
                                            	Point operator / (double a) {return Point(x/a,y/a);}
                                            	double absv() {return sqrt(norm());}
                                            	double norm() {return x*x+y*y;}
                                            	bool operator < (const Point &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const Point &p) const{
                                            		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
                                            	}
                                            };
                                            typedef Point Vector;
                                     #define pl pair<int,pas>
                                            struct Segment{
                                            Point p1,p2;
                                            };
                                             double dot(Vector a,Vector b){
                                            	return a.x*b.x+a.y*b.y;
                                            }
                                            double cross(Vector a,Vector b){
                                            	return a.x*b.y-a.y*b.x;
                                            }
                                        
                bool parareru(Point a,Point b,Point c,Point d){
                //	if(abs(cross(a-b,d-c))<EPS)cout<<"dd "<<cross(a-b,d-c)<<endl;
                	return abs(cross(a-b,d-c))<EPS;
                }
                double distance_ls_p(Point a, Point b, Point c) {
                  if ( dot(b-a, c-a) < EPS ) return (c-a).absv();
                  if ( dot(a-b, c-b) < EPS ) return (c-b).absv();
                  return abs(cross(b-a, c-a)) / (b-a).absv();
                }
                bool is_intersected_ls(Segment a,Segment b) {
                	if(a.p1==b.p1||a.p2==b.p1||a.p1==b.p2||a.p2==b.p2) return false;
                	if(parareru((a.p2),(a.p1),(a.p1),(b.p2))&&parareru((a.p2),(a.p1),(a.p1),(b.p1))){
                //		cout<<"sss"<<endl;
                		if(dot(a.p1-b.p1,a.p1-b.p2)<EPS) return true;
                		if(dot(a.p2-b.p1,a.p2-b.p2)<EPS) return true;
                		if(dot(a.p1-b.p1,a.p2-b.p1)<EPS) return true;
                		if(dot(a.p1-b.p2,a.p2-b.p2)<EPS) return true;
                		return false;
                	}
                  else return ( cross(a.p2-a.p1, b.p1-a.p1) * cross(a.p2-a.p1, b.p2-a.p1) < EPS ) && ( cross(b.p2-b.p1, a.p1-b.p1) * cross(b.p2-b.p1, a.p2-b.p1) < EPS );
                }
                 
                double segment_dis(Segment a,Segment b){
                	if(is_intersected_ls(a,b))return 0;
                	double r=distance_ls_p(a.p1, a.p2, b.p1);
                	r=min(r,distance_ls_p(a.p1, a.p2, b.p2));
                	r=min(r,distance_ls_p(b.p1, b.p2, a.p2));
                	r=min(r,distance_ls_p(b.p1, b.p2, a.p1));
                	return r;
                }
                Point intersection_ls(Segment a, Segment b) {
                  Point ba = b.p2-b.p1;
                  double d1 = abs(cross(ba, a.p1-b.p1));
                  double d2 = abs(cross(ba, a.p2-b.p1));
                  double t = d1 / (d1 + d2);
                 
                  return a.p1 + (a.p2-a.p1) * t;
                }
 */                
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                                double distans(double x1,double y1,double x2,double y2){
                                	double rr=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                                	return sqrt(rr);
                                	
                                }
                                int mod;
int extgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
    
                                
                int pr[1000010];
                int inv[1000010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	wa%=warukazu;
                	if(rr%2==1) return ((ll)beki(wa,rr-1,warukazu)*(ll)wa)%warukazu;
                	ll zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
    double bekid(double w,int r){
    	if(r==0) return 1.0;
    	if(r==1) return w;
    	if(r%2) return bekid(w,r-1)*w;
    	double f=bekid(w,r/2);
    	return f*f;
    }
                
    			int comb(int nn,int rr){
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
                
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                	for(int i=0;i<ert;i++) inv[i]=beki(pr[i],mod-2,mod);
                	
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
    
                                     //----------------kokomade tenpure------------

int a[100];
int dp[2][4][8][4][9][9][401][8]={};  
 signed main(){

    	       cin.tie(0);
   			ios::sync_with_stdio(false);
int n;
 	cin>>n;
 	vector<int> ve;
 	ve.pb(0);
 	//assert(n<=10);
 	for(int i=1;i<=n;i++){
 		int y;
 		cin>>y;
 	//a	assert(y<=3);
 		for(int j=0;j<y;j++)ve.pb(i);
 	}
 	mod=10007;
 	n=ve.size()-1;
 	dp[1][0][0][0][2][0][0][0]=1;
 	for(int i=1;i<n;i++){
 		if(ve[i]==ve[i+1]){
 		//	cout<<i<<endl;
 			for(int j=0;j<4;j++)for(int k=0;k<8&&2*j+k<=8;k++)for(int l=0;l<4&&k+2*l<=8;l++)for(int m=0;m<9&&2*j+k+m<=8;m++)for(int p=0;p<9&&k+2*l+p<=8;p++)for(int q=0;q<=400;q++)for(int r=0;r<8&&k+2*l+p+r<=8;r++)if(dp[i%2][j][k][l][m][p][q][r]){
 				int ok=i+1-j-k-l-m-p-q-r;
 		//		cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<m<<" "<<p<<" "<<" "<<q<<" "<<r<<" "<<ok<<" "<<dp[i][j][k][l][m][p][q][r]<<endl;
 				assert(ok>=0);
 				if(ok>0){
 					dp[(i+1)%2][j][k][l][m+2][p][q][r]+=dp[i%2][j][k][l][m][p][q][r]*ok;
 					dp[(i+1)%2][j][k][l][m+2][p][q][r]%=mod;
 				}
 				if(r>0){
 					dp[(i+1)%2][j][k+1][l][m+1][p][q][r-1]+=dp[i%2][j][k][l][m][p][q][r]*r;
 					dp[(i+1)%2][j][k+1][l][m+1][p][q][r-1]%=mod;
 				}
 				if(q>0){
 					dp[(i+1)%2][j][k][l][m+2][p][q-1][r]+=dp[i%2][j][k][l][m][p][q][r]*q;
 					dp[(i+1)%2][j][k][l][m+2][p][q-1][r]%=mod;
 				}
 				if(p>0){
 					dp[(i+1)%2][j][k+1][l][m+1][p-1][q][r]+=dp[i%2][j][k][l][m][p][q][r]*p;
 					dp[(i+1)%2][j][k+1][l][m+1][p-1][q][r]%=mod;
 				}
 				if(m>0){
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]+=dp[i%2][j][k][l][m][p][q][r]*m;
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]%=mod;
 				}
 				if(l>0){
 					dp[(i+1)%2][j][k+2][l-1][m][p][q][r]+=dp[i%2][j][k][l][m][p][q][r]*l;
 					dp[(i+1)%2][j][k+2][l-1][m][p][q][r]%=mod;
 				}
 				if(k>0){
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]+=dp[i%2][j][k][l][m][p][q][r]*k;
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]%=mod;
 				}
 				if(j>0){
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]+=dp[i%2][j][k][l][m][p][q][r]*j;
 					dp[(i+1)%2][j+1][k][l][m][p][q][r]%=mod;
 				}
 				dp[i%2][j][k][l][m][p][q][r]=0;
 			}
 		}
 		else{
 			 			for(int j=0;j<4;j++)for(int k=0;k<8&&2*j+k<=8;k++)for(int l=0;l<4&&k+2*l<=8;l++)for(int m=0;m<9&&2*j+k+m<=8;m++)for(int p=0;p<9&&k+2*l+p<=8;p++)for(int q=0;q<=400;q++)for(int r=0;r<8&&k+2*l+p+r<=8;r++)if(dp[i%2][j][k][l][m][p][q][r]){
//for(int j=0;j<4;j++)for(int k=0;k<8&&2*j+k<=8;k++)for(int l=0;l<4&&k+2*l<=8;l++)for(int m=0;m<9&&2*j+k+m<=8;m++)for(int p=0;p<9;p++)for(int q=0;q<=400;q++)for(int r=0;r<8;r++)if(dp[i%2][j][k][l][m][p][q][r]){
 				int ok=i+1-j-k-l-m-p-r-q;
 		//		cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<m<<" "<<p<<" "<<q<<" "<<r<<" "<<ok<<" "<<dp[i][j][k][l][m][p][q][r]<<endl;
 				int nj=0;
 				int nk=0;
 				int nl=j;
 				int nm=0;
 				int np=m;
 				int nq=l+q+r;
 				int nr=k;
 				int nok=ok+p;
 		//		cout<<" "<<nj<<" "<<nk<<" "<<nl<<" "<<nm<<" "<<np<<" "<<nq<<" "<<nr<<" "<<nok<<endl;
 				assert(nok>=0);
 				if(nok>0){
 					dp[(i+1)%2][nj][nk][nl][nm+2][np][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*nok;
 					dp[(i+1)%2][nj][nk][nl][nm+2][np][nq][nr]%=mod;
 				}
 				if(nr>0){
 					dp[(i+1)%2][nj][nk+1][nl][nm+1][np][nq][nr-1]+=dp[i%2][j][k][l][m][p][q][r]*nr;
 					dp[(i+1)%2][nj][nk+1][nl][nm+1][np][nq][nr-1]%=mod;
 				}
 				if(nq>0){
 					dp[(i+1)%2][nj][nk][nl][nm+2][np][nq-1][nr]+=dp[i%2][j][k][l][m][p][q][r]*nq;
 					dp[(i+1)%2][nj][nk][nl][nm+2][np][nq-1][nr]%=mod;
 				}
 				if(np>0){
 					dp[(i+1)%2][nj][nk+1][nl][nm+1][np-1][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*np;
 					dp[(i+1)%2][nj][nk+1][nl][nm+1][np-1][nq][nr]%=mod;
 				}
 				if(nm>0){
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*nm;
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]%=mod;
 				}
 				if(nl>0){
 					dp[(i+1)%2][nj][nk+2][nl-1][nm][np][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*nl;
 					dp[(i+1)%2][nj][nk+2][nl-1][nm][np][nq][nr]%=mod;
 				}
 				if(nk>0){
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*nk;
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]%=mod;
 				}
 				if(nj>0){
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]+=dp[i%2][j][k][l][m][p][q][r]*nj;
 					dp[(i+1)%2][nj+1][nk][nl][nm][np][nq][nr]%=mod;
 				}
	dp[i%2][j][k][l][m][p][q][r]=0;
 			}
 		}
 		//for(int j=0;j<4;j++)for(int k=0;k<8;k++)for(int l=0;l<4;l++)for(int m=0;m<9;m++)for(int p=0;p<9;p++)for(int q=0;q<=400;q++)for(int r=0;r<8;r++)dp[i%2][j][k][l][m][p][q][r]=0;
 	}
 
 	int ans=0;
 	for(int m=0;m<9;m++)for(int p=0;p<9;p++){
// 		if(dp[n][0][0][0][m][p][0][0])cout<<m<<" "<<p<<endl;
 		ans+=dp[n%2][0][0][0][m][p][0][0];
 		ans%=mod;
 	}

 	cout<<ans<<endl;

 	return 0;
  }
accuracy: 1
time_ms: 1140
memory_kb: 22868
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int MAX = 2100;
const int MOD = 10007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i = 2; i < MAX; i++){
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k){
    if(n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

long long dp[110][410][10][10][5] = {0}; // a <= 401, b <= 8, c <= 8, d <= 3
int main() {
    COMinit();
    int N; cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i];
    
    dp[0][0][0][0][0] = 1;
    int s = 0;
    for (int i = 0; i < N; ++i) {
        for (int a = 0; a <= s+1; ++a) {
            for (int b = 0; b < 8; ++b) {
                for (int c = 0; c < 8; ++c) {
                    for (int d = 0; d < 4; ++d) {
                        int e = s + 1 - a - b - c - d;
                        if (e < 0) continue;
                        if (!dp[i][a][b][c][d]) continue;

                        for (int a2 = 0; a2 <= a; ++a2) {
                            for (int b2 = 0; b2 <= b && a2 + b2 <= A[i]; ++b2) {
                                for (int c2 = 0; c2 <= c && a2 + b2 +c2 <= A[i]; ++c2) {
                                    for (int d2 = 0; d2 <= d && a2 + b2 +c2 + d2 <= A[i]; ++d2) {
                                        for (int e2 = 0; e2 <= e && a2 + b2 +c2 + d2 + e2 <= A[i]; ++e2) {
                                            int s2 = a2 + b2 + c2 + d2 + e2;
                                            int r2 = A[i] - s2;
                                            long long fact = COM(a, a2);
                                            fact = (fact * COM(b, b2)) % MOD;
                                            fact = (fact * COM(c, c2)) % MOD;
                                            fact = (fact * COM(d, d2)) % MOD;
                                            fact = (fact * COM(e, e2)) % MOD;
                                            fact = (fact * COM(r2 + s2 - 1, r2)) % MOD;
                                            
                                            int na = a + c + d - a2 - c2 - d2;
                                            int nb = (a2 + e2) * 2 + b2 + c2;
                                            int nc = b2 + c2 + d2 * 2;
                                            int nd = r2;
                                            //int ne = b + e - b2 - e2;
                                            dp[i+1][na][nb][nc][nd] += dp[i][a][b][c][d] * fact % MOD;
                                            dp[i+1][na][nb][nc][nd] %= MOD;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        s += A[i];
    }
    long long res = 0;
    for (int b = 0; b < 8; ++b) res = (res + dp[N][0][b][0][0]) % MOD;
    for (int i = 0; i < N; ++i) res = (res * fac[A[i]]) % MOD;
    cout << res << endl;
}
accuracy: 0.7407407407407407
time_ms: 1130
memory_kb: 79040
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int MAX = 2100;
const int MOD = 10007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i = 2; i < MAX; i++){
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k){
    if(n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

long long dp[110][410][10][10][5] = {0}; // a <= 401, b <= 8, c <= 8, d <= 3
int main() {
    COMinit();
    int N; cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i];
    
    dp[0][0][0][0][0] = 1;
    int s = 0;
    for (int i = 0; i < N; ++i) {
        for (int a = 0; a <= s; ++a) {
            for (int b = 0; b < 8; ++b) {
                for (int c = 0; c < 8; ++c) {
                    for (int d = 0; d < 4; ++d) {
                        int e = s + 1 - a - b - c - d;
                        if (e < 0) continue;
                        if (!dp[i][a][b][c][d]) continue;

                        for (int a2 = 0; a2 <= a; ++a2) {
                            for (int b2 = 0; b2 <= b && a2 + b2 <= A[i]; ++b2) {
                                for (int c2 = 0; c2 <= c && a2 + b2 +c2 <= A[i]; ++c2) {
                                    for (int d2 = 0; d2 <= d && a2 + b2 +c2 + d2 <= A[i]; ++d2) {
                                        for (int e2 = 0; e2 <= e && a2 + b2 +c2 + d2 + e2 <= A[i]; ++e2) {
                                            int s2 = a2 + b2 + c2 + d2 + e2;
                                            int r2 = A[i] - s2;
                                            long long fact = COM(a, a2);
                                            fact = (fact * COM(b, b2)) % MOD;
                                            fact = (fact * COM(c, c2)) % MOD;
                                            fact = (fact * COM(d, d2)) % MOD;
                                            fact = (fact * COM(e, e2)) % MOD;
                                            fact = (fact * COM(r2 + s2 - 1, r2)) % MOD;
                                            
                                            int na = a + c + d - a2 - c2 - d2;
                                            int nb = (a2 + e2) * 2 + b2 + c2;
                                            int nc = b2 + c2 + d2 * 2;
                                            int nd = r2;
                                            //int ne = b + e - b2 - e2;
                                            dp[i+1][na][nb][nc][nd] += dp[i][a][b][c][d] * fact % MOD;
                                            dp[i+1][na][nb][nc][nd] %= MOD;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        s += A[i];
    }
    long long res = 0;
    for (int b = 0; b < 8; ++b) res = (res + dp[N][0][b][0][0]) % MOD;
    for (int i = 0; i < N; ++i) res = (res * fac[A[i]]) % MOD;
    cout << res << endl;
}
accuracy: 0.7407407407407407
time_ms: 1130
memory_kb: 78940
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int MAX = 2100;
const int MOD = 10007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i = 2; i < MAX; i++){
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k){
    if(n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

long long dp[110][410][10][10][5] = {0}; // a <= 401, b <= 8, c <= 8, d <= 3
int main() {
    COMinit();
    int N; cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i];
    
    dp[0][0][0][0][0] = 1;
    int s = 0;
    for (int i = 0; i < N; ++i) {
        for (int a = 0; a <= 401; ++a) {
            for (int b = 0; b < 8; ++b) {
                for (int c = 0; c < 8; ++c) {
                    for (int d = 0; d < 4; ++d) {
                        int e = s + 1 - a - b - c - d;
                        if (e < 0) continue;
                        if (!dp[i][a][b][c][d]) continue;

                        for (int a2 = 0; a2 <= a; ++a2) {
                            for (int b2 = 0; b2 <= b && a2 + b2 <= A[i]; ++b2) {
                                for (int c2 = 0; c2 <= c && a2 + b2 +c2 <= A[i]; ++c2) {
                                    for (int d2 = 0; d2 <= d && a2 + b2 +c2 + d2 <= A[i]; ++d2) {
                                        for (int e2 = 0; e2 <= e && a2 + b2 +c2 + d2 + e2 <= A[i]; ++e2) {
                                            int s2 = a2 + b2 + c2 + d2 + e2;
                                            int r2 = A[i] - s2;
                                            long long fact = COM(a, a2);
                                            fact = (fact * COM(b, b2)) % MOD;
                                            fact = (fact * COM(c, c2)) % MOD;
                                            fact = (fact * COM(d, d2)) % MOD;
                                            fact = (fact * COM(e, e2)) % MOD;
                                            fact = (fact * COM(r2 + s2 - 1, r2)) % MOD;
                                            
                                            int na = a + c + d - a2 - c2 - d2;
                                            int nb = (a2 + e2) * 2 + b2 + c2;
                                            int nc = b2 + c2 + d2 * 2;
                                            int nd = r2;
                                            //int ne = b + e - b2 - e2;
                                            dp[i+1][na][nb][nc][nd] += dp[i][a][b][c][d] * fact % MOD;
                                            dp[i+1][na][nb][nc][nd] %= MOD;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        s += A[i];
    }
    long long res = 0;
    for (int b = 0; b < 8; ++b) res = (res + dp[N][0][b][0][0]) % MOD;
    for (int i = 0; i < N; ++i) res = (res * fac[A[i]]) % MOD;
    cout << res << endl;
}
accuracy: 0.7407407407407407
time_ms: 1140
memory_kb: 79036
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int MAX = 2100;
const int MOD = 10007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i = 2; i < MAX; i++){
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k){
    if(n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

long long dp[110][410][10][10][5] = {0}; // a <= 401, b <= 8, c <= 8, d <= 3
int main() {
    COMinit();
    int N; cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i];
    
    dp[0][0][0][0][0] = 1;
    int s = 0;
    for (int i = 0; i < N; ++i) {
        for (int a = 0; a <= 401; ++a) {
            for (int b = 0; b < 8; ++b) {
                for (int c = 0; c < 8; ++c) {
                    for (int d = 0; d < 4; ++d) {
                        int e = s + 1 - a - b - c - d;
                        if (e < 0) continue;
                        if (!dp[i][a][b][c][d]) continue;

                        for (int a2 = 0; a2 <= a; ++a2) {
                            for (int b2 = 0; b2 <= b && a2 + b2 <= A[i]; ++b2) {
                                for (int c2 = 0; c2 <= c && a2 + b2 +c2 <= A[i]; ++c2) {
                                    for (int d2 = 0; d2 <= d && a2 + b2 +c2 + d2 <= A[i]; ++d2) {
                                        for (int e2 = 0; e2 <= e && a2 + b2 +c2 + d2 + e2 <= A[i]; ++e2) {
                                            int s2 = a2 + b2 + c2 + d2 + e2;
                                            int r2 = A[i] - s2;
                                            long long fact = COM(a, a2);
                                            fact = (fact * COM(b, b2)) % MOD;
                                            fact = (fact * COM(c, c2)) % MOD;
                                            fact = (fact * COM(d, d2)) % MOD;
                                            fact = (fact * COM(e, e2)) % MOD;
                                            fact = (fact * COM(r2 + s2 - 1, r2)) % MOD;
                                            
                                            int na = a + c + d - a2 - c2 - d2;
                                            int nb = (a2 + e2) * 2 + b2 + c2;
                                            int nc = b2 + c2 + d2 * 2;
                                            int nd = r2;
                                            //int ne = b + e - b2 - e2;
                                            dp[i+1][na][nb][nc][nd] += dp[i][a][b][c][d] * fact % MOD;
                                            dp[i+1][na][nb][nc][nd] %= MOD;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        s += A[i];
    }
    long long res = 0;
    for (int b = 0; b <= 8; ++b) res = (res + dp[N][0][b][0][0]) % MOD;
    for (int i = 0; i < N; ++i) res = (res * fac[A[i]]) % MOD;
    cout << res << endl;
}
accuracy: 0.7407407407407407
time_ms: 1150
memory_kb: 79052
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define syosu(x) fixed<<setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef pair<double,double> pdd;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<string> vs;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<int,P> pip;
typedef vector<pip> vip;
const int inf=1<<30;
const ll INF=1ll<<60;
const double pi=acos(-1);
const double eps=1e-9;
//const ll mod=1e9+7;
const int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};

const int M=405,mod=10007;
ll n,C[M][M],dp[101][M][8][4];

int main(){
	cin>>n;
	C[0][0]++;
	for(int i=0;i<M-1;i++) for(int j=0;j<=i;j++){
		(C[i+1][j]+=C[i][j])%=mod;
		(C[i+1][j+1]+=C[i][j])%=mod;
	}
	dp[0][0][0][0]++;
	int S=0,N,N_=0;
	for(int i=0;i<n;i++){
		cin>>N;
		ll t=1;
		for(int j=1;j<=N;j++) (t*=j)%=mod;
		for(int j=0;j<=S+1;j++) for(int k=0;k<8;k++) for(int l=0;l<4;l++) for(int x=1;x<=min(S+1,N);x++) if(dp[i][j][k][l]){
			int q=2*(N_-l)-k;
			for(int J=0;J<=min(x,j);J++) for(int K=0;K<=min(x-J,k);K++) for(int L=0;L<=min(x-J-K,l);L++) for(int Q=0;Q<=min(x-J-K-L,q);Q++){
				(dp[i+1][j+k+l-J-K-L][K+2*L+Q][N-x]+=t*C[N-1][x-1]*C[j][J]*C[k][K]*C[l][L]*C[q][Q]*C[S-j-k-l-q+1][x-J-K-L-Q]*dp[i][j][k][l])%=mod;
			}
		}
		S+=N;N_=N;
	}
	cout<<dp[n][0][0][0]<<endl;
}
accuracy: 1
time_ms: 130
memory_kb: 9720
final_rank: 1

code_snippet: #include"bits/stdc++.h"
using namespace std;
#define LL long long
#define PB push_back
#define MP make_pair

const int MOD = 10007;
int N, A[100], sum[100];

int memo1[5] ={ 0,1,2,6,24 };
int memo2[5][5] ={ {0,0,0,0,0},{0,1,0,0,0},{0,1,1,0,0},{0,1,2,1,0},{0,1,3,3,1} };
/*
a := 国i
b := i-2以下の国どうしの問題隣接箇所
c := 国i-1と国i-3以下の隣接箇所(今はok)
d := 国i-1とi-2間の隣接箇所
e := 国i-1どうしの隣接箇所
f := それ以外の隣接箇所
*/
short dp[100][400][9][8][4];
bool visited[100][400][9][8][4] ={};
int solve(int a, int b, int c, int d, int e){
	if(a == N){
		if(b == 0 && d == 0 && e == 0) return 1;
		else return 0;
	}
	if(visited[a][b][c][d][e]) return dp[a][b][c][d][e];
	visited[a][b][c][d][e] = true;
	int f = sum[a] - b - c - d - e;
	int nc = 0;
	int nd = 0;
	LL ret = 0;
	for(int i=1; i<=A[a]; i++){ //何個の塊
		LL baai = memo1[A[a]] * memo2[A[a]][i] / memo1[i];
		for(int j=0; j<5; j++){
			if(j == 0){ if(b == 0) continue; baai*=b; b--; nc+=2; }
			if(j == 1){ if(c == 0) continue; baai*=c; c--; nc++; nd++; }
			if(j == 2){ if(d == 0) continue; baai*=d; d--; nc++; nd++; }
			if(j == 3){ if(e == 0) continue; baai*=e; e--; nd+=2; }
			if(j == 4){ if(f == 0) continue; baai*=f; f--; nc+=2; }
			if(i == 1) ret += baai * solve(a+1, b+d+e, nc, nd, A[a]-i);
			for(int k=0; k<5 && i>1; k++){
				if(k == 0){ if(b == 0) continue; baai*=b; b--; nc+=2; }
				if(k == 1){ if(c == 0) continue; baai*=c; c--; nc++; nd++; }
				if(k == 2){ if(d == 0) continue; baai*=d; d--; nc++; nd++; }
				if(k == 3){ if(e == 0) continue; baai*=e; e--; nd+=2; }
				if(k == 4){ if(f == 0) continue; baai*=f; f--; nc+=2; }
				if(i == 2) ret += baai * solve(a+1, b+d+e, nc, nd, A[a]-i);
				for(int l=0; l<5 && i>2; l++){
					if(l == 0){ if(b == 0) continue; baai*=b; b--; nc+=2; }
					if(l == 1){ if(c == 0) continue; baai*=c; c--; nc++; nd++; }
					if(l == 2){ if(d == 0) continue; baai*=d; d--; nc++; nd++; }
					if(l == 3){ if(e == 0) continue; baai*=e; e--; nd+=2; }
					if(l == 4){ if(f == 0) continue; baai*=f; f--; nc+=2; }
					if(i == 3) ret += baai * solve(a+1, b+d+e, nc, nd, A[a]-i);
					for(int m=0; m<5 && i>3; m++){
						if(m == 0){ if(b == 0) continue; baai*=b; b--; nc+=2; }
						if(m == 1){ if(c == 0) continue; baai*=c; c--; nc++; nd++; }
						if(m == 2){ if(d == 0) continue; baai*=d; d--; nc++; nd++; }
						if(m == 3){ if(e == 0) continue; baai*=e; e--; nd+=2; }
						if(m == 4){ if(f == 0) continue; baai*=f; f--; nc+=2; }
						ret += baai * solve(a+1, b+d+e, nc, nd, A[a]-i);
						if(m == 0){ b++; nc-=2; baai/=b; }
						if(m == 1){ c++; nc--; nd--; baai/=c; }
						if(m == 2){ d++; nc--; nd--; baai/=d; }
						if(m == 3){ e++; nd-=2; baai/=e; }
						if(m == 4){ f++; nc-=2; baai/=f; }
					}
					if(l == 0){ b++; nc-=2; baai/=b; }
					if(l == 1){ c++; nc--; nd--; baai/=c; }
					if(l == 2){ d++; nc--; nd--; baai/=d; }
					if(l == 3){ e++; nd-=2; baai/=e; }
					if(l == 4){ f++; nc-=2; baai/=f; }
				}
				if(k == 0){ b++; nc-=2; baai/=b; }
				if(k == 1){ c++; nc--; nd--; baai/=c; }
				if(k == 2){ d++; nc--; nd--; baai/=d; }
				if(k == 3){ e++; nd-=2; baai/=e; }
				if(k == 4){ f++; nc-=2; baai/=f; }
			}
			if(j == 0){ b++; nc-=2; baai/=b; }
			if(j == 1){ c++; nc--; nd--; baai/=c; }
			if(j == 2){ d++; nc--; nd--; baai/=d; }
			if(j == 3){ e++; nd-=2; baai/=e; }
			if(j == 4){ f++; nc-=2; baai/=f; }
		}
	}
	return dp[a][b][c][d][e] = ret%MOD;
}

int main(){
	scanf("%d", &N);
	for(int i=0; i<N; i++) scanf("%d%", A+i);
	sum[0] = 1;
	for(int i=1; i<N; i++) sum[i] = sum[i-1] + A[i-1];
	printf("%d\n", solve(0,0,0,0,0));
}
accuracy: 1
time_ms: 2840
memory_kb: 20272
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int MAX = 2100;
const int MOD = 10007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i = 2; i < MAX; i++){
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k){
    if(n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

long long dp[110][410][10][10][5] = {0}; // a <= 401, b <= 8, c <= 8, d <= 3
int main() {
    COMinit();
    int N; cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i];
    
    dp[0][0][0][0][0] = 1;
    int s = 0;
    for (int i = 0; i < N; ++i) {
        for (int a = 0; a <= 401; ++a) {
            for (int b = 0; b <= 8; ++b) {
                for (int c = 0; c <= 8; ++c) {
                    for (int d = 0; d <= 3; ++d) {
                        int e = s + 1 - a - b - c - d;
                        if (e < 0) continue;
                        if (!dp[i][a][b][c][d]) continue;

                        for (int a2 = 0; a2 <= a; ++a2) {
                            for (int b2 = 0; b2 <= b && a2 + b2 <= A[i]; ++b2) {
                                for (int c2 = 0; c2 <= c && a2 + b2 +c2 <= A[i]; ++c2) {
                                    for (int d2 = 0; d2 <= d && a2 + b2 +c2 + d2 <= A[i]; ++d2) {
                                        for (int e2 = 0; e2 <= e && a2 + b2 +c2 + d2 + e2 <= A[i]; ++e2) {
                                            int s2 = a2 + b2 + c2 + d2 + e2;
                                            int r2 = A[i] - s2;
                                            long long fact = COM(a, a2);
                                            fact = (fact * COM(b, b2)) % MOD;
                                            fact = (fact * COM(c, c2)) % MOD;
                                            fact = (fact * COM(d, d2)) % MOD;
                                            fact = (fact * COM(e, e2)) % MOD;
                                            fact = (fact * COM(r2 + s2 - 1, r2)) % MOD;
                                            
                                            int na = a + c + d - a2 - c2 - d2;
                                            int nb = (a2 + e2) * 2 + b2 + c2;
                                            int nc = b2 + c2 + d2 * 2;
                                            int nd = r2;
                                            //int ne = b + e - b2 - e2;
                                            dp[i+1][na][nb][nc][nd] += dp[i][a][b][c][d] * fact % MOD;
                                            dp[i+1][na][nb][nc][nd] %= MOD;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        s += A[i];
    }
    long long res = 0;
    for (int b = 0; b <= 8; ++b) res = (res + dp[N][0][b][0][0]) % MOD;
    for (int i = 0; i < N; ++i) res = (res * fac[A[i]]) % MOD;
    cout << res << endl;
}
accuracy: 1
time_ms: 1360
memory_kb: 80620
final_rank: 7