Problem:
Problem J:
SolveMe
$N$ 個の部屋があり, それぞれの部屋の床にはうさぎの絵が描かれている. あなたが部屋 $r$ のうさぎの絵の右耳の部分に乗ると, あなたは部屋 $A[r]$ に書かれたうさぎのしっぽの上にテレポートする. 同様に, 部屋 $r$ のうさぎの絵の左耳の部分に乗ると, 部屋 $B[r]$ に書かれたうさぎのしっぽの上にテレポートする.
整数 $X$, $Y$, $Z$ が与えられる. ねこは, 以下の条件を満たすようにテレポートを設定しようとしている. テレポートの $N^{2N}$ 通りの設定方法のうち, 条件を満たすものは何通りか, mod 1,000,000,007で求めよ.
条件: 任意の部屋 $r$ に対し, $r$ から右耳にちょうど $X$ 回乗り, 左耳にちょうど 1 回乗り, 右耳にちょうど $Y$ 回乗り, 左耳にちょうど 1 回乗り, 右耳にちょうど $Z$ 回乗ると, $r$ に戻る.
Constraints
$N$ will be between 1 and 1,000, inclusive.
$X$, $Y$, $Z$ will be between 0 and 1,000,000,000,000,000,000, inclusive.
Input
入力は以下の形式で与えられる:
$N$ $X$ $Y$ $Z$
Output
テレポートの設定方法を 1,000,000,007 で割ったあまりを表す整数を 1 行に出力せよ.
Sample Input 1
3 1 0 1
Sample Output 1
18
Sample Input 2
5 8 5 8
Sample Output 2
120

Submitted solutions:

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

using ll = long long;
#define REP(i,n) for(ll i=0; i<ll(n); i++)
template<class T>using V = vector<T>;

const int MOD = 1000000007;

struct Modint {
    int x;
    Modint() : x(0) {}
    Modint(int y) : x(y%MOD) { if(x < 0) x += MOD; }
    Modint& operator+=(Modint r){ x += r.x; if(x >= MOD){ x-=MOD; } return *this; }
    Modint& operator-=(Modint r){ x -= r.x; if(x < 0){ x+=MOD; } return *this; }
    Modint& operator*=(Modint r){ x = ll(x) * r.x % MOD; return *this; }
    Modint operator+(Modint r) const { auto a = *this; a += r; return a; }
    Modint operator-(Modint r) const { auto a = *this; a -= r; return a; }
    Modint operator*(Modint r) const { auto a = *this; a *= r; return a; }
    Modint pow(ll i) const {
        Modint a = *this;
        Modint r = 1;
        while(i){
            if(i%2) r *= a;
            a *= a;
            i /= 2;
        }
        return r;
    }
    Modint inv() const { return pow(MOD-2); }
};

using Mint = Modint;

V<Mint> fact, ifact, invmod;
void precalc_fact(int Z){
    fact.assign(Z+1, 1);
    for(int i=1; i<=Z; i++) fact[i] = fact[i-1] * i;
    ifact.assign(Z+1, fact[Z].inv());
    for(int i=Z; i>=1; i--) ifact[i-1] = ifact[i] * i;
    invmod.assign(Z+1, 0);
    for(int i=1; i<=Z; i++) invmod[i] = ifact[i] * fact[i-1];
}

V<Mint> conv_sp(ll n, ll k, const V<Mint>& a, const V<Mint>& b){
    V<Mint> res(n+1);
    for(ll d=0; d*k<=n; d++){
        for(ll f=d*k; f<=n; f++){
            res[f] += a[f-d*k] * b[d];
        }
    }
    return res;
}

ll gcd(ll x, ll y){
    if(!y) return x;
    return gcd(y, x%y);
}

V<Mint> hav1(ll n, ll k, V<ll> wids){
    //cout << "hav1 "; for(auto a : wids){ cout << a << " ";} cout << endl;
    V<Mint> res(n/k+1);
    res[0] = 1;
    for(ll x : wids){
        V<Mint> tmp(n/x+1);
        for(ll t=0; t<ll(tmp.size()); t++){
            tmp[t] = ifact[t] * invmod[x].pow(t);
        }
        res = conv_sp(n/k, x/k, res, tmp);
    }
    return res;
}

V<Mint> hav2(ll n, ll k, V<ll> wids){
    //cout << "hav2 "; for(auto a : wids){ cout << a << " ";} cout << endl;
    ll z = n / k;
    V<Mint> res(z+1);
    res[0] = 1;
    for(ll x : wids){
        V<Mint> tmp(n/x+1);
        for(ll t=0; t<ll(tmp.size()); t++){
            tmp[t] = ifact[t] * (invmod[x/k] * Mint(k).pow(x/k-1)).pow(t);
        }
        res = conv_sp(n/k, x/k, res, tmp);
    }
    for(ll i=0; i<=z; i++) res[i] *= fact[i];
    return res;
}

void testcase(){
    ll N; cin >> N;
    precalc_fact(N);
    ll X, Y, Z; cin >> X >> Y >> Z;
    ll Q = X + Z - Y;
    if(Q < 0) Q = -Q;
    V<V<ll>> TA(N+1), TB(N+1);
    for(ll i=1; i<=N; i++) TA[i/gcd(i,Q)].push_back(i);
    for(ll i=1; i<=N; i++) TB[i/gcd(i,2)].push_back(i);
    V<Mint> dp(N+1); dp[0] = 1;
    for(ll i=1; i<=N; i++){
        auto X = hav1(N, i, TA[i]);
        auto Y = hav2(N, i, TB[i]);
        for(ll k=0; k*i<=N; k++) X[k] *= Y[k];
        dp = conv_sp(N, i, dp, X);
    }
    Mint ans = dp[N] * fact[N];
    if(X == 0 && Y == 0 && Z == 0){
      ans *= ifact[N];
      ans *= Mint(N).pow(N);
    }
    cout << ans.x << endl;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3712
final_rank: 3

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

using ll = long long;
#define REP(i,n) for(ll i=0; i<ll(n); i++)
template<class T>using V = vector<T>;

const int MOD = 1000000007;

struct Modint {
    int x;
    Modint() : x(0) {}
    Modint(int y) : x(y%MOD) { if(x < 0) x += MOD; }
    Modint& operator+=(Modint r){ x += r.x; if(x >= MOD){ x-=MOD; } return *this; }
    Modint& operator-=(Modint r){ x -= r.x; if(x < 0){ x+=MOD; } return *this; }
    Modint& operator*=(Modint r){ x = ll(x) * r.x % MOD; return *this; }
    Modint operator+(Modint r) const { auto a = *this; a += r; return a; }
    Modint operator-(Modint r) const { auto a = *this; a -= r; return a; }
    Modint operator*(Modint r) const { auto a = *this; a *= r; return a; }
    Modint pow(ll i) const {
        Modint a = *this;
        Modint r = 1;
        while(i){
            if(i%2) r *= a;
            a *= a;
            i /= 2;
        }
        return r;
    }
    Modint inv() const { return pow(MOD-2); }
};

using Mint = Modint;

V<Mint> fact, ifact, invmod;
void precalc_fact(int Z){
    fact.assign(Z+1, 1);
    for(int i=1; i<=Z; i++) fact[i] = fact[i-1] * i;
    ifact.assign(Z+1, fact[Z].inv());
    for(int i=Z; i>=1; i--) ifact[i-1] = ifact[i] * i;
    invmod.assign(Z+1, 0);
    for(int i=1; i<=Z; i++) invmod[i] = ifact[i] * fact[i-1];
}

V<Mint> conv_sp(ll n, ll k, const V<Mint>& a, const V<Mint>& b){
    V<Mint> res(n+1);
    for(ll d=0; d*k<=n; d++){
        for(ll f=d*k; f<=n; f++){
            res[f] += a[f-d*k] * b[d];
        }
    }
    return res;
}

ll gcd(ll x, ll y){
    if(!y) return x;
    return gcd(y, x%y);
}

V<Mint> hav1(ll n, ll k, V<ll> wids){
    //cout << "hav1 "; for(auto a : wids){ cout << a << " ";} cout << endl;
    V<Mint> res(n/k+1);
    res[0] = 1;
    for(ll x : wids){
        V<Mint> tmp(n/x+1);
        for(ll t=0; t<ll(tmp.size()); t++){
            tmp[t] = ifact[t] * invmod[x].pow(t);
        }
        res = conv_sp(n/k, x/k, res, tmp);
    }
    return res;
}

V<Mint> hav2(ll n, ll k, V<ll> wids){
    //cout << "hav2 "; for(auto a : wids){ cout << a << " ";} cout << endl;
    ll z = n / k;
    V<Mint> res(z+1);
    res[0] = 1;
    for(ll x : wids){
        V<Mint> tmp(n/x+1);
        for(ll t=0; t<ll(tmp.size()); t++){
            tmp[t] = ifact[t] * (invmod[x/k] * Mint(k).pow(x/k-1)).pow(t);
        }
        res = conv_sp(n/k, x/k, res, tmp);
    }
    for(ll i=0; i<=z; i++) res[i] *= fact[i];
    return res;
}

void testcase(){
    ll N; cin >> N;
    precalc_fact(N);
    ll X, Y, Z; cin >> X >> Y >> Z;
    ll Q = X + Z - Y;
    if(Q < 0) Q = -Q;
    V<V<ll>> TA(N+1), TB(N+1);
    for(ll i=1; i<=N; i++) TA[i/gcd(i,Q)].push_back(i);
    for(ll i=1; i<=N; i++) TB[i/gcd(i,2)].push_back(i);
    V<Mint> dp(N+1); dp[0] = 1;
    for(ll i=1; i<=N; i++){
        auto X = hav1(N, i, TA[i]);
        auto Y = hav2(N, i, TB[i]);
        for(ll k=0; k*i<=N; k++) X[k] *= Y[k];
        dp = conv_sp(N, i, dp, X);
    }
    Mint ans = dp[N] * fact[N];
    cout << ans.x << endl;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 0.9024390243902439
time_ms: 10
memory_kb: 3712
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 1005;
const int mod = 1000000007;
inline int qp(int a, int b) {
	int res = 1;
	while (b) {
		if (b & 1) res = 1ll * res * a % mod;
		a = 1ll * a * a % mod;
		b >>= 1;
	}
	return res;
}
int n, fact[N], ifact[N], inv[N];
inline void init_fact(int n = 1000) {
	inv[1] = 1;
	for (int i = 2; i <= n; i++)
		inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
	fact[0] = ifact[0] = 1;
	for (int i = 1; i <= n; i++) {
		fact[i] = 1ll * fact[i - 1] * i % mod;
		ifact[i] = 1ll * ifact[i - 1] * inv[i] % mod;
	}
}
inline void solve(int f[N][N], vector<int> vf[N]) {
	for (int i = 1; i <= n; i++) {
		f[i][0] = 1;
		for (int j : vf[i]) {
			int pw = 1ll * qp(i, j - 1) * inv[j] % mod;
			for (int k = n / i; k >= j; k--) {
				for (int c = 1, prd = 1; c <= k / j; c++) {
					prd = 1ll * prd * pw % mod;
					f[i][k] = (f[i][k] + 1ll * f[i][k - c * j] * prd % mod * ifact[c] % mod) % mod;
				}
			}
		}
		for (int j = 0; j <= n / i; j++)
			f[i][j] = 1ll * f[i][j] * fact[j] % mod;
	}
}
vector<int> vf[N], vg[N];
int f[N][N], g[N][N], dp[N][N];
int main() {
	init_fact();
	long long k, X, Y, Z;
	scanf("%d%lld%lld%lld", &n, &X, &Y, &Z);
	k = abs(X + Z - Y);
	for (int i = 1; i <= n; i++) {
		int g1 = __gcd((long long)i, k);
		int g2 = __gcd(i, 2);
		vf[i / g1].push_back(g1);
		vg[i / g2].push_back(g2);
	}
	solve(f, vf);
	solve(g, vg);
	if (!X && !Y && !Z) {
		printf("%lld\n", 1ll * qp(n, n) * g[1][n] % mod);
		return 0;
	}
	dp[0][0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= n; j++) {
			for (int c = 0, prd = 1; c <= j / i; c++, prd = 1ll * prd * inv[i] % mod) {
				dp[i][j] = (dp[i][j] + 1ll * dp[i - 1][j - c * i] * f[i][c] % mod * g[i][c] % mod * ifact[c] % mod * prd % mod) % mod;
			}
		}
	}
	int ans = 1ll * dp[n][n] * fact[n] % mod;
	printf("%d\n", ans);
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 15456
final_rank: 9

code_snippet: // AOJ #2378 SolveMe
// 2025.4.6

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;
const int MAX = 2005;

ll gcd(ll a, ll b) {
    ll t;
    while (b != 0) t = a % b, a = b, b = t;
    return a;
}

int modPow(int x, int t) {
    int res = 1;
    while (t > 0) {
        if (t & 1) res = (ll)res * x % MOD;
        x = (ll)x * x % MOD;
        t >>= 1;
    }
    return res;
}

int f[MAX][MAX];
vector<int> vArr[MAX];
int iv[MAX];
int gArr[MAX], ngArr[MAX];
int hArr[MAX];

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    ll X, Y, Z;
    cin >> n >> X >> Y >> Z;
    X += Z - Y;
    if (X < 0) X = -X;

    iv[0] = 1;
    for (int i = 1; i <= n; i++) iv[i] = modPow(i, MOD - 2);

    for (int i = 1; i <= n; i++){
        ll g = gcd((ll)i, X);
        int key = i / (int)g;
        vArr[key].push_back(i);
    }

    for (int i = 1; i <= n; i++){
        f[i][0] = 1;
        f[i][1] = (i & 1);
        for (int j = 2; j <= n; j++){
            ll term1 = (ll)f[i][j - 2] * (j - 1) % MOD * i % MOD;
            ll term2 = (ll)f[i][j - 1] * ((i & 1) ? 1 : 0) % MOD;
            f[i][j] = (term1 + term2) % MOD;
        }
    }

    if (X == 0 && Y == 0) {
        int cur = 1;
        for (int i = 1; i <= n; i++) cur = (ll)cur * n % MOD;
        cout << (ll)cur * f[1][n] % MOD << endl;
        return 0;
    }

    hArr[0] = 1;
    for (int i = 1; i <= n; i++){
        if (vArr[i].empty()) continue;
        memset(gArr, 0, sizeof(gArr));
        gArr[0] = 1;

        int m = n / i;
        for (int x : vArr[i]) {
            memcpy(ngArr, gArr, sizeof(gArr));
            int t = x / i;
            int mul = 1;
            for (int j = 1; j * t <= m; j++){
                mul = (int)((ll)mul * iv[x] % MOD * iv[j] % MOD);
                for (int k = 0; k + j * t <= m; k++)
                    ngArr[k + j * t] = (ngArr[k + j * t] + (ll)mul * gArr[k]) % MOD;
            }
            memcpy(gArr, ngArr, sizeof(gArr));
        }

        for (int j = n; j >= 1; j--){
            for (int k = 1; i * k <= j; k++){
                hArr[j] = (hArr[j] + (ll)hArr[j - i * k] * f[i][k] % MOD * gArr[k]) % MOD;
            }
        }
    }
    ll ans = hArr[n];
    for (int i = 1; i <= n; i++) ans = ans * i % MOD;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11532
final_rank: 5

code_snippet: // AOJ #2378 SolveMe
// 2025.4.6

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;

ll gcd(ll a, ll b) {
    ll t;
    while (b != 0) t = a % b, a = b, b = t;
    return a;
}

template<int M>
struct ModInt {
    ll val;
    ModInt(ll v = 0) {
        val = v % M;
        if(val < 0) val += M;
    }
    ModInt& operator+=(const ModInt &other) {
        val += other.val;
        if(val >= M) val -= M;
        return *this;
    }
    ModInt& operator-=(const ModInt &other) {
        val -= other.val;
        if(val < 0) val += M;
        return *this;
    }
    ModInt& operator*=(const ModInt &other) {
        val = (val * other.val) % M;
        return *this;
    }
    ModInt pow(ll exp) const {
        ModInt res(1), base(*this);
        while(exp > 0) {
            if(exp & 1) res *= base;
            base *= base;
            exp >>= 1;
        }
        return res;
    }
    ModInt inv() const {
        return pow(M - 2);
    }
    ModInt& operator/=(const ModInt &other) {
        *this *= other.inv();
        return *this;
    }
};

template<int M>
ModInt<M> operator+(ModInt<M> a, const ModInt<M>& b) { a += b; return a; }
template<int M>
ModInt<M> operator-(ModInt<M> a, const ModInt<M>& b) { a -= b; return a; }
template<int M>
ModInt<M> operator*(ModInt<M> a, const ModInt<M>& b) { a *= b; return a; }
template<int M>
ModInt<M> operator/(ModInt<M> a, const ModInt<M>& b) { a /= b; return a; }

using mint = ModInt<MOD>;

struct Binom {
    vector<mint> fact, inv, invFact;
    int size;
    Binom(int n) : size(n) {
        fact.resize(n);
        inv.resize(n);
        invFact.resize(n);
        fact[0] = mint(1);
        for (int i = 1; i < n; i++) fact[i] = fact[i - 1] * mint(i);
        inv[1] = mint(1);
        for (int i = 2; i < n; i++) inv[i] = mint(MOD - MOD / i) * inv[MOD % i];
        invFact[0] = mint(1);
        for (int i = 1; i < n; i++) invFact[i] = invFact[i - 1] * inv[i];
    }
    mint comb(int n, int k) const {
        if (k < 0 || k > n) return mint(0);
        return fact[n] * invFact[k] * invFact[n - k];
    }
};

Binom bc(5005);

mint grouping(int e, int k) {
    return bc.fact[k * e] * bc.invFact[k] * (bc.invFact[e].pow(k));
}

vector<mint> computeSub(int N, ll p, ll e) {
    int K = N / e;
    vector<ll> Ds;
    for (ll d = e; d <= N; d += e) if (e * gcd(d, p) == d) Ds.push_back(d);
    int m = Ds.size();
    vector<vector<mint>> dp(m + 1, vector<mint>(K + 1, mint(0)));
    dp[0][0] = mint(1);
    for (int i = 0; i < m; i++) {
        int d = (int)Ds[i];
        int g = d / e;
        mint mult = bc.fact[g - 1] * mint(e).pow(g - 1);
        for (int j = 0; j <= K; j++) {
            mint fac(1);
            for (int l = 0; j + l * g <= K; l++) {
                dp[i + 1][j + l * g] += dp[i][j] * bc.comb(j + l * g, j) * grouping(g, l) * fac;
                fac *= mult;
            }
        }
    }
    return dp[m];
}

int main(){
    int N;
    ll X, Y, Z;
    cin >> N >> X >> Y >> Z;
    mint ans;
    if (X + Y + Z == 0) {
        vector<mint> gdp = computeSub(N, 2, 1);
        ans = gdp[N] * mint(N).pow(N);
    } else {
        ll t = X - Y + Z;
        if (t < 0) t = -t;
        vector<vector<mint>> dp(N + 1, vector<mint>(N + 1, mint(0)));
        dp[0][0] = mint(1);
        for (int e = 1; e <= N; e++) {
            vector<mint> fdp = computeSub(N, t, e);
            vector<mint> gdp = computeSub(N, 2, e);
            for (int n = 0; n <= N; n++) {
                mint fac(1);
                for (int k = 0; n + k * e <= N; k++) {
                    dp[e][n + k * e] += dp[e - 1][n] * bc.comb(n + k * e, n) * grouping(e, k) * fac * fdp[k] * gdp[k];
                    fac *= bc.fact[e - 1];
                }
            }
        }
        ans = dp[N][N];
    }
    cout << ans.val << endl;
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 11440
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v)        (int)(v).size()
#define all(v)       (v).begin(), (v).end()

constexpr int mod = 1000000007;
struct mint {
	ll v;
	mint(ll x = 0) {
		v = x;
		v %= mod;
		if(v < 0) v += mod;
	}
	mint operator+(mint o) { return v + o.v; }
	mint operator-(mint o) { return v - o.v; }
	mint operator*(mint o) { return v * o.v; }
	mint pow(ll k) {
		assert(k >= 0);
		mint ret = 1, a = v;
		while(k) {
			if(k & 1) ret = ret * a;
			a = a * a;
			k >>= 1;
		}
		return ret;
	}
	mint inv() { return pow(mod - 2); }
	mint operator/(mint o) { return v * o.inv().v; }
};

vector<mint> fac, finv;

ll naive(int n, int x, int y, int z) {
	ll ret = 0;
	vi p(n);
	iota(all(p), 0);
	do {
		vi q(n);
		iota(all(q), 0);
		do {
			vi f(n), nx;
			iota(all(f), 0);
			rep(t, x) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, y) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, z) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			bool ok = 1;
			rep(i, n) ok &= f[i] == i;
			ret += ok;
		} while(next_permutation(all(q)));
	} while(next_permutation(all(p)));
	return ret;
}

void init(int n) {
	fac.resize(n + 1);
	finv.resize(n + 1);
	fac[0] = finv[0] = 1;
	rep(i, n) fac[i + 1] = fac[i] * (i + 1);
	finv[n] = fac[n].inv();
	for(int i = n - 1; i >= 1; i--) finv[i] = finv[i + 1] * (i + 1);
}
mint binom(int n, int k) {
	if(min(n, k) < 0 or n < k) return 0;
	return fac[n] * finv[k] * finv[n - k];
}

int main() {
	int n;
	ll X, Y, Z;
	cin >> n >> X >> Y >> Z;

	if(X == 0 and Y == 0 and Z == 0) {
		vector<mint> a{1, 1};
		rng(i, 2, n + 1) a.push_back(a[i - 1] + a[i - 2] * (i - 1));
		cout << (a[n] * mint(n).pow(n)).v << endl;
		return 0;
	}

	init(1000);
	// f^2=h^k
	ll k = abs(Y - X - Z);


	//  (i = j / gcd(j, k)) * gcd(j, k)
	auto make_table = [&](ll x) {
		vector table(n + 1, vector(n + 1, mint(0)));
		rng(i, 1, n + 1) {
			vi tmp;
			rng(j, 1, n + 1) {
				if(j / gcd(j, x) != i) continue;
				tmp.push_back(gcd(j, x));
			}
			if(tmp.empty()) continue;
			int m = sz(tmp);
			// j個のグループを、tmp[k]以下を使って分配する個数
			vector dp(m + 1, vector(n / i + 1, mint(0)));
			dp[0][0] = 1;
			rep(id, m) {
				mint pw = mint(i).pow(tmp[id] - 1);
				rep(j, n / i + 1) {
					mint tar = 1;
					for(int u = 0; u * tmp[id] <= j; u++) {
						dp[id + 1][j] = dp[id + 1][j] + dp[id][j - u * tmp[id]] * tar * finv[u];
						tar = tar * binom(j - u * tmp[id], tmp[id]) * fac[tmp[id] - 1] * pw;
					}
				}
			}
			rep(j, n / i + 1) table[i][j] = dp.back()[j];
		}
		return table;
	};

	auto lt = make_table(2);
	auto rt = make_table(k);


	vector dp(n + 1, vector(n + 1, mint(0)));
	dp[0][n] = 1;
	rng(i, 1, n + 1) {
		rep(j, n + 1) {
			dp[i][j] = dp[i][j] + dp[i - 1][j];
			//完成形のグループを決め打つ
			//それを適切に分配する
			mint cur = 1;
			for(int u = 1; u * i <= j; u++) {
				cur = cur * binom(j - i * (u - 1), i) * fac[i - 1];
				mint tar = cur / fac[u];
				mint lef = lt[i][u], rig = rt[i][u];
				dp[i][j - u * i] = dp[i][j - u * i] + dp[i - 1][j] * tar * lef * rig;
			}
		}
	}
	cout << dp[n][0].v << endl;
}
accuracy: 1
time_ms: 440
memory_kb: 26828
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v)        (int)(v).size()
#define all(v)       (v).begin(), (v).end()

constexpr int mod = 1000000007;
struct mint {
	ll v;
	mint(ll x = 0) {
		v = x;
		v %= mod;
		if(v < 0) v += mod;
	}
	mint operator+(mint o) { return v + o.v; }
	mint operator-(mint o) { return v - o.v; }
	mint operator*(mint o) { return v * o.v; }
	mint pow(ll k) {
		assert(k >= 0);
		mint ret = 1, a = v;
		while(k) {
			if(k & 1) ret = ret * a;
			a = a * a;
			k >>= 1;
		}
		return ret;
	}
	mint inv() { return pow(mod - 2); }
	mint operator/(mint o) { return v * o.inv().v; }
};

vector<mint> fac, finv;

ll naive(int n, int x, int y, int z) {
	ll ret = 0;
	vi p(n);
	iota(all(p), 0);
	do {
		vi q(n);
		iota(all(q), 0);
		do {
			vi f(n), nx;
			iota(all(f), 0);
			rep(t, x) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, y) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, z) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			bool ok = 1;
			rep(i, n) ok &= f[i] == i;
			ret += ok;
		} while(next_permutation(all(q)));
	} while(next_permutation(all(p)));
	return ret;
}

void init(int n) {
	fac.resize(n + 1);
	finv.resize(n + 1);
	fac[0] = finv[0] = 1;
	rep(i, n) fac[i + 1] = fac[i] * (i + 1);
	finv[n] = fac[n].inv();
	for(int i = n - 1; i >= 1; i--) finv[i] = finv[i + 1] * (i + 1);
}
mint binom(int n, int k) {
	if(min(n, k) < 0 or n < k) return 0;
	return fac[n] * finv[k] * finv[n - k];
}

int main() {
	int n;
	ll X, Y, Z;
	cin >> n >> X >> Y >> Z;

	init(1000);
	// f^2=h^k
	ll k = abs(Y - X - Z);

	if(!k) {
		vector<mint> a{1, 1};
		rng(i, 2, n + 1) a.push_back(a[i - 1] * i + a[i - 2] * i * (i - 1) * (i - 1));
		cout << a[n].v << endl;
		return 0;
	}
	//  (i = j / gcd(j, k)) * gcd(j, k)
	auto make_table = [&](ll x) {
		vector table(n + 1, vector(n + 1, mint(0)));
		rng(i, 1, n + 1) {
			vi tmp;
			rng(j, 1, n + 1) {
				if(j / gcd(j, x) != i) continue;
				tmp.push_back(gcd(j, x));
			}
			if(tmp.empty()) continue;
			int m = sz(tmp);
			// j個のグループを、tmp[k]以下を使って分配する個数
			vector dp(m + 1, vector(n / i + 1, mint(0)));
			dp[0][0] = 1;
			rep(id, m) {
				mint pw = mint(i).pow(tmp[id] - 1);
				rep(j, n / i + 1) {
					mint tar = 1;
					for(int u = 0; u * tmp[id] <= j; u++) {
						dp[id + 1][j] = dp[id + 1][j] + dp[id][j - u * tmp[id]] * tar * finv[u];
						tar = tar * binom(j - u * tmp[id], tmp[id]) * fac[tmp[id] - 1] * pw;
					}
				}
			}
			rep(j, n / i + 1) table[i][j] = dp.back()[j];
		}
		return table;
	};

	auto lt = make_table(2);
	auto rt = make_table(k);


	vector dp(n + 1, vector(n + 1, mint(0)));
	dp[0][n] = 1;
	rng(i, 1, n + 1) {
		rep(j, n + 1) {
			dp[i][j] = dp[i][j] + dp[i - 1][j];
			//完成形のグループを決め打つ
			//それを適切に分配する
			mint cur = 1;
			for(int u = 1; u * i <= j; u++) {
				cur = cur * binom(j - i * (u - 1), i) * fac[i - 1];
				mint tar = cur / fac[u];
				mint lef = lt[i][u], rig = rt[i][u];
				dp[i][j - u * i] = dp[i][j - u * i] + dp[i - 1][j] * tar * lef * rig;
			}
		}
	}
	cout << dp[n][0].v << endl;
}
accuracy: 0.9024390243902439
time_ms: 440
memory_kb: 26656
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v)        (int)(v).size()
#define all(v)       (v).begin(), (v).end()

constexpr int mod = 1000000007;
struct mint {
	ll v;
	mint(ll x = 0) {
		v = x;
		v %= mod;
		if(v < 0) v += mod;
	}
	mint operator+(mint o) { return v + o.v; }
	mint operator-(mint o) { return v - o.v; }
	mint operator*(mint o) { return v * o.v; }
	mint pow(ll k) {
		assert(k >= 0);
		mint ret = 1, a = v;
		while(k) {
			if(k & 1) ret = ret * a;
			a = a * a;
			k >>= 1;
		}
		return ret;
	}
	mint inv() { return pow(mod - 2); }
	mint operator/(mint o) { return v * o.inv().v; }
};

vector<mint> fac, finv;

ll naive(int n, int x, int y, int z) {
	ll ret = 0;
	vi p(n);
	iota(all(p), 0);
	do {
		vi q(n);
		iota(all(q), 0);
		do {
			vi f(n), nx;
			iota(all(f), 0);
			rep(t, x) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, y) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, z) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			bool ok = 1;
			rep(i, n) ok &= f[i] == i;
			ret += ok;
		} while(next_permutation(all(q)));
	} while(next_permutation(all(p)));
	return ret;
}

void init(int n) {
	fac.resize(n + 1);
	finv.resize(n + 1);
	fac[0] = finv[0] = 1;
	rep(i, n) fac[i + 1] = fac[i] * (i + 1);
	finv[n] = fac[n].inv();
	for(int i = n - 1; i >= 1; i--) finv[i] = finv[i + 1] * (i + 1);
}
mint binom(int n, int k) {
	if(min(n, k) < 0 or n < k) return 0;
	return fac[n] * finv[k] * finv[n - k];
}

int main() {
	int n;
	ll X, Y, Z;
	cin >> n >> X >> Y >> Z;
	if(!X and !Y and !Z) {
		cout << mint(n).pow(n * 2).v << endl;
		return 0;
	}
	// cout << naive(n, X, Y, Z) << endl;
	init(1000);
	// f^2=h^k
	ll k = abs(Y - X - Z);
	if(!k) {
		cout << mint(n).pow(n * 2).v << endl;
		return 0;
	}
	//  (i = j / gcd(j, k)) * gcd(j, k)
	auto make_table = [&](ll x) {
		vector table(n + 1, vector(n + 1, mint(0)));
		rng(i, 1, n + 1) {
			vi tmp;
			rng(j, 1, n + 1) {
				if(j / gcd(j, x) != i) continue;
				tmp.push_back(gcd(j, x));
			}
			if(tmp.empty()) continue;
			int m = sz(tmp);
			// j個のグループを、tmp[k]以下を使って分配する個数
			vector dp(m + 1, vector(n / i + 1, mint(0)));
			dp[0][0] = 1;
			rep(id, m) {
				mint pw = mint(i).pow(tmp[id] - 1);
				rep(j, n / i + 1) {
					mint tar = 1;
					for(int u = 0; u * tmp[id] <= j; u++) {
						dp[id + 1][j] = dp[id + 1][j] + dp[id][j - u * tmp[id]] * tar * finv[u];
						tar = tar * binom(j - u * tmp[id], tmp[id]) * fac[tmp[id] - 1] * pw;
					}
				}
			}
			rep(j, n / i + 1) table[i][j] = dp.back()[j];
		}
		return table;
	};

	auto lt = make_table(2);
	auto rt = make_table(k);


	vector dp(n + 1, vector(n + 1, mint(0)));
	dp[0][n] = 1;
	rng(i, 1, n + 1) {
		rep(j, n + 1) {
			dp[i][j] = dp[i][j] + dp[i - 1][j];
			//完成形のグループを決め打つ
			//それを適切に分配する
			mint cur = 1;
			for(int u = 1; u * i <= j; u++) {
				cur = cur * binom(j - i * (u - 1), i) * fac[i - 1];
				mint tar = cur / fac[u];
				mint lef = lt[i][u], rig = rt[i][u];
				dp[i][j - u * i] = dp[i][j - u * i] + dp[i - 1][j] * tar * lef * rig;
			}
		}
	}
	cout << dp[n][0].v << endl;
}
accuracy: 0.9024390243902439
time_ms: 440
memory_kb: 26660
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v)        (int)(v).size()
#define all(v)       (v).begin(), (v).end()

constexpr int mod = 1000000007;
struct mint {
	ll v;
	mint(ll x = 0) {
		v = x;
		v %= mod;
		if(v < 0) v += mod;
	}
	mint operator+(mint o) { return v + o.v; }
	mint operator-(mint o) { return v - o.v; }
	mint operator*(mint o) { return v * o.v; }
	mint pow(ll k) {
		assert(k >= 0);
		mint ret = 1, a = v;
		while(k) {
			if(k & 1) ret = ret * a;
			a = a * a;
			k >>= 1;
		}
		return ret;
	}
	mint inv() { return pow(mod - 2); }
	mint operator/(mint o) { return v * o.inv().v; }
};

vector<mint> fac, finv;

ll naive(int n, int x, int y, int z) {
	ll ret = 0;
	vi p(n);
	iota(all(p), 0);
	do {
		vi q(n);
		iota(all(q), 0);
		do {
			vi f(n), nx;
			iota(all(f), 0);
			rep(t, x) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, y) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, z) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			bool ok = 1;
			rep(i, n) ok &= f[i] == i;
			ret += ok;
		} while(next_permutation(all(q)));
	} while(next_permutation(all(p)));
	return ret;
}

void init(int n) {
	fac.resize(n + 1);
	finv.resize(n + 1);
	fac[0] = finv[0] = 1;
	rep(i, n) fac[i + 1] = fac[i] * (i + 1);
	finv[n] = fac[n].inv();
	for(int i = n - 1; i >= 1; i--) finv[i] = finv[i + 1] * (i + 1);
}
mint binom(int n, int k) {
	if(min(n, k) < 0 or n < k) return 0;
	return fac[n] * finv[k] * finv[n - k];
}

int main() {
	int n;
	ll X, Y, Z;
	cin >> n >> X >> Y >> Z;
	// cout << naive(n, X, Y, Z) << endl;
	init(1000);
	// f^xgf^yf^z=id
	ll k = abs(Y - X - Z);
	if(!k) {
		cout << mint(n).pow(n).v << endl;
		return 0;
	}
	//  (i = j / gcd(j, k)) * gcd(j, k)
	auto make_table = [&](ll x) {
		vector table(n + 1, vector(n + 1, mint(0)));
		rng(i, 1, n + 1) {
			vi tmp;
			rng(j, 1, n + 1) {
				if(j / gcd(j, x) != i) continue;
				tmp.push_back(gcd(j, x));
			}
			if(tmp.empty()) continue;
			int m = sz(tmp);
			// j個のグループを、tmp[k]以下を使って分配する個数
			vector dp(m + 1, vector(n / i + 1, mint(0)));
			dp[0][0] = 1;
			rep(id, m) {
				mint pw = mint(i).pow(tmp[id] - 1);
				rep(j, n / i + 1) {
					mint tar = 1;
					for(int u = 0; u * tmp[id] <= j; u++) {
						dp[id + 1][j] = dp[id + 1][j] + dp[id][j - u * tmp[id]] * tar * finv[u];
						tar = tar * binom(j - u * tmp[id], tmp[id]) * fac[tmp[id] - 1] * pw;
					}
				}
			}
			rep(j, n / i + 1) table[i][j] = dp.back()[j];
		}
		return table;
	};

	auto lt = make_table(2);
	auto rt = make_table(k);


	vector dp(n + 1, vector(n + 1, mint(0)));
	dp[0][n] = 1;
	rng(i, 1, n + 1) {
		rep(j, n + 1) {
			dp[i][j] = dp[i][j] + dp[i - 1][j];
			//完成形のグループを決め打つ
			//それを適切に分配する
			mint cur = 1;
			for(int u = 1; u * i <= j; u++) {
				cur = cur * binom(j - i * (u - 1), i) * fac[i - 1];
				mint tar = cur / fac[u];
				mint lef = lt[i][u], rig = rt[i][u];
				dp[i][j - u * i] = dp[i][j - u * i] + dp[i - 1][j] * tar * lef * rig;
			}
		}
	}
	cout << dp[n][0].v << endl;
}
accuracy: 0.9024390243902439
time_ms: 440
memory_kb: 26684
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v)        (int)(v).size()
#define all(v)       (v).begin(), (v).end()

constexpr int mod = 1000000007;
struct mint {
	ll v;
	mint(ll x = 0) {
		v = x;
		v %= mod;
		if(v < 0) v += mod;
	}
	mint operator+(mint o) { return v + o.v; }
	mint operator-(mint o) { return v - o.v; }
	mint operator*(mint o) { return v * o.v; }
	mint pow(ll k) {
		assert(k >= 0);
		mint ret = 1, a = v;
		while(k) {
			if(k & 1) ret = ret * a;
			a = a * a;
			k >>= 1;
		}
		return ret;
	}
	mint inv() { return pow(mod - 2); }
	mint operator/(mint o) { return v * o.inv().v; }
};

vector<mint> fac, finv;

ll naive(int n, int x, int y, int z) {
	ll ret = 0;
	vi p(n);
	iota(all(p), 0);
	do {
		vi q(n);
		iota(all(q), 0);
		do {
			vi f(n), nx;
			iota(all(f), 0);
			rep(t, x) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, y) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			nx = f;
			rep(i, n) nx[q[i]] = f[i];
			f = nx;
			rep(t, z) {
				nx = f;
				rep(i, n) {
					nx[p[i]] = f[i];
				}
				f = nx;
			}
			bool ok = 1;
			rep(i, n) ok &= f[i] == i;
			ret += ok;
		} while(next_permutation(all(q)));
	} while(next_permutation(all(p)));
	return ret;
}

void init(int n) {
	fac.resize(n + 1);
	finv.resize(n + 1);
	fac[0] = finv[0] = 1;
	rep(i, n) fac[i + 1] = fac[i] * (i + 1);
	finv[n] = fac[n].inv();
	for(int i = n - 1; i >= 1; i--) finv[i] = finv[i + 1] * (i + 1);
}
mint binom(int n, int k) {
	if(min(n, k) < 0 or n < k) return 0;
	return fac[n] * finv[k] * finv[n - k];
}

int main() {
	int n;
	ll X, Y, Z;
	cin >> n >> X >> Y >> Z;
	// cout << naive(n, X, Y, Z) << endl;
	init(1000);
	// f^xgf^yf^z=id
	ll k = abs(Y - X - Z);
	if(!k) {
		cout << mint(n).pow(n).v << endl;
		return 0;
	}
	//  (i = j / gcd(j, k)) * gcd(j, k)
	auto make_table = [&](int x) {
		vector table(n + 1, vector(n + 1, mint(0)));
		rng(i, 1, n + 1) {
			vi tmp;
			rng(j, 1, n + 1) {
				if(j / gcd(j, x) != i) continue;
				tmp.push_back(gcd(j, x));
			}
			if(x == 1 and i == 4) cerr << "ts:" << tmp.size() << endl;
			if(tmp.empty()) continue;
			int m = sz(tmp);
			// j個のグループを、tmp[k]以下を使って分配する個数
			vector dp(m + 1, vector(n + 1, mint(0)));
			dp[0][0] = 1;
			rep(id, m) {
				rep(j, n + 1) {
					mint tar = 1;
					for(int u = 0; u * tmp[id] <= j; u++) {
						dp[id + 1][j] = dp[id + 1][j] + dp[id][j - u * tmp[id]] * tar * finv[u];
						tar = tar * binom(j - u * tmp[id], tmp[id]) * fac[tmp[id] - 1];
						tar = tar * mint(i).pow(tmp[id] - 1);
					}
				}
			}
			rep(j, n + 1) table[i][j] = dp.back()[j];
		}
		return table;
	};

	auto lt = make_table(2);
	auto rt = make_table(k);


	vector dp(n + 1, vector(n + 1, mint(0)));
	dp[0][n] = 1;
	rng(i, 1, n + 1) {
		rep(j, n + 1) {
			dp[i][j] = dp[i][j] + dp[i - 1][j];
			//完成形のグループを決め打つ
			//それを適切に分配する
			mint cur = 1;
			for(int u = 1; u * i <= j; u++) {
				cur = cur * binom(j - i * (u - 1), i) * fac[i - 1];
				mint tar = cur / fac[u];
				mint lef = lt[i][u], rig = rt[i][u];
				dp[i][j - u * i] = dp[i][j - u * i] + dp[i - 1][j] * tar * lef * rig;
			}
		}
	}
	cout << dp[n][0].v << endl;
}
accuracy: 0.24390243902439024
time_ms: 7170
memory_kb: 20788
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
using ll=long long;
#define all(p) p.begin(),p.end()
const int mod=1e9+7;
/*
q(p^Y)q(p^(X+Z))==id
となる長さ N の順列の組 (p,q) の場合の数

D=abs(X+Z-Y)
として、
QQ(p^D)=id
の順列のくみ (p,Q) の場合の数

Q^{2}=p^{D}
の順列の組 (p,Q) の場合の数

p^{D} は偶数置換と奇数置換からなるが、偶数置換は大きさが同じやつが偶数個ないとダメ
*/

/*
mod=an+b
a/(mod-b)=1/n
-a/b=1/n
*/

/*
サイズ s のサイクル a 個 をb組マージする(2*b<=a)
このときの場合の数は、

組の決め方 -> aP2b/b!2^b
マージの仕方 -> s^b
*/
int main(){
	ll N,X,Y,Z;
	cin>>N>>X>>Y>>Z;
	ll D=abs(X+Z-Y);
	// combination
	vector<ll> rev(N+1,1),fact(N+1,1),fact_rev(N+1,1);
	for(ll i=1;i<=N;i++){
		fact[i]=(fact[i-1]*i)%mod;
		if(i!=1){
			rev[i]=(-(mod/i)*rev[mod%i])%mod;
			rev[i]=(rev[i]+mod)%mod;
		}
		fact_rev[i]=(fact_rev[i-1]*rev[i])%mod;
	}
	/*
	auto Com=[&](int a,int b)->ll{
		return (((fact[a]*fact_rev[b])%mod)*fact_rev[a-b])%mod;
	};*/
	auto P=[&](int a,int b)->ll{
		return (fact[a]*fact_rev[a-b])%mod;
	};
	//a^{b}
	auto my_pow=[&](ll a,ll b)->ll{
		a%=mod;
		ll ans=1;
		while(b){
			if(b&1) ans=(ans*a)%mod;
			b>>=1;
			a=(a*a)%mod;
		}
		return ans;
	};

	if(X+Y+Z==0){
		ll ans=0;
		for(ll i=0;i*2<=N;i++){
			ll tmp=(my_pow(rev[2],i)*P(N,i*2))%mod;
			tmp=(tmp*fact_rev[i])%mod;
			ans=(ans+tmp)%mod;
		}
		cout<<(ans*my_pow(N,N))%mod<<"\n";
		return 0;
	}

	vector<vector<ll>> base(N+1,vector<ll>(N+1));
	rep(i,N) base[i+1][0]=1;
	for(ll i=1;i<=N;i++){
		ll div=__gcd(i,D);
		ll siz=i/div;
		for(ll j=(N/siz)*siz;j>=0;j-=siz){
			if(base[siz][j]==0) continue;
			ll tmp=base[siz][j];
			for(ll k=1;k*i+j<=N;k++){
				tmp=(tmp*rev[i])%mod;
				tmp=(tmp*rev[k])%mod;
				base[siz][k*i+j]=(base[siz][k*i+j]+tmp)%mod;
			}
		}
	}
	vector<ll> dp(N+1);
	dp[0]=1;
	for(ll i=1;i<=N;i++){
		vector<ll> n_dp(N+1);
		for(ll j=1;j*i<=N;j++){
			//cout<<i<<" "<<j<<" "<<(base[i][j*i]*6)%mod<<"\n";
			if(i%2==0&&j%2==1) continue;
			ll tmp=0;
			if(i%2==0){
				tmp=(fact[j]*fact_rev[j/2])%mod;
				tmp=(tmp*my_pow(i*rev[2],j/2))%mod;
			}else{
				for(ll b=0;b*2<=j;b++){
					ll v=(P(j,2*b)*fact_rev[b])%mod;
					v=(v*my_pow(i*rev[2],b))%mod;
					tmp=(tmp+v)%mod;
				}
			}
			tmp=(tmp*base[i][i*j])%mod;
			for(ll k=N-i*j;k>=0;k--){
				n_dp[k+i*j]=(n_dp[k+i*j]+dp[k]*tmp)%mod;
			}
		}
		rep(j,N+1) dp[j]=(dp[j]+n_dp[j])%mod;
	}
	cout<<(dp[N]*fact[N])%mod<<"\n";
}
accuracy: 1
time_ms: 10
memory_kb: 11224
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int N=2005,mod=1e9+7;
ll qpow(ll n,int k){
	ll ans=1;
	while(k){
		if(k&1)ans=ans*n%mod;
		n=n*n%mod;
		k>>=1;
	}
	return ans;
}
ll fac[N],ifac[N];
ll inv[N];
ll C(int x,int y){
	if(x<0||y<0||x<y)return 0;
	return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
ll ff[N];
ll n;
ll X,Y,Z;
void solve1(){//X=Y=Z=0
	ll ans=0; 
	ff[0]=1;
	for(int i=2;i<N;i+=2){
		ff[i]=(i-1)*ff[i-2]%mod;
	}
	for(int i=0;i<=n;i++){
		int x=n-i;
		if(x&1)continue;
		//i个自环
		ans+=C(n,i)*ff[x]%mod;ans%=mod;
	} 
	for(int i=1;i<=n;i++)ans=ans*n%mod;
	cout<<ans<<"\n";
}
ll dp[N][N];
ll f[N],g[N];
ll k;
ll pd[N][N],pw[N][N];
ll gcd(ll x,ll y){
	return __gcd(x,y);
}
vector<int>v;
void workf(int len){//2
	v.clear();
	for(int i=1;i<=n;i++){
		if(i/gcd(i,2)==len)v.push_back(i);
	}
	for(int i=0;i<=n;i++)f[i]=0;
	for(int i=0;i<=n;i++)pd[0][i]=0;
	pd[0][0]=1;
	for(int i=0;i<v.size();i++){
		int L=v[i];
		int t=gcd(L,2);
		for(int j=0;j<=n/len;j++)pd[i+1][j]=0;
		for(int j=0;j<=n/len;j++){
			ll coef=1;ll c=fac[t-1]*qpow(L/t,t-1)%mod;
			for(int x=0;j+x*t<=n/len;x++){ 
				pd[i+1][j+x*t]+=pd[i][j]*C(j+t*x,j)%mod*fac[x*t]%mod*ifac[x]%mod*pw[t][x]%mod*coef%mod;
				pd[i+1][j+x*t]%=mod;
				coef*=c%mod;coef%=mod;
			}
		}
	} 
	for(int i=0;i<=n/len;i++)f[i]=pd[v.size()][i];
}
void workg(int len){//k
	v.clear();
	for(int i=1;i<=n;i++){
		if(i/gcd(i,k)==len)v.push_back(i);
	}
	for(int i=0;i<=n;i++)g[i]=0;
	for(int i=0;i<=n;i++)pd[0][i]=0;
	pd[0][0]=1;
	for(int i=0;i<v.size();i++){
		int L=v[i];//一个长度为L的会分裂成gcd(L,k)个长度为L/gcd的 
		int t=gcd(L,k);//一个长度为L的可以得到t个长度为len的 
		for(int j=0;j<=n/len;j++)pd[i+1][j]=0;
		for(int j=0;j<=n/len;j++){
			ll coef=1;ll c=fac[t-1]*qpow(L/t,t-1)%mod;
			for(int x=0;j+x*t<=n/len;x++){
				pd[i+1][j+x*t]+=pd[i][j]*C(j+t*x,j)%mod*fac[x*t]%mod*ifac[x]%mod*pw[t][x]%mod*coef%mod;
				pd[i+1][j+x*t]%=mod;
				coef*=c%mod;coef%=mod;
			}
		}
	} 
	for(int i=0;i<=n/len;i++)g[i]=pd[v.size()][i];
}
void solve2(){
	k=X+Z-Y;k=abs(k);
	dp[0][0]=1;
	for(int i=1;i<=n;i++){
		workf(i);workg(i);		
		for(int j=0;j<=n;j++){
			ll coef=1;
			for(int x=0;j+x*i<=n;x++){
				dp[i][j+x*i]+=dp[i-1][j]*C(j+x*i,j)%mod*fac[x*i]%mod*ifac[x]%mod*pw[i][x]%mod*coef%mod*f[x]%mod*g[x]%mod;
				dp[i][j+x*i]%=mod;
				coef*=fac[i-1];coef%=mod;
			}
		}
	}
	cout<<dp[n][n]<<"\n";
}
signed main(){
    cin.tie(0);cout.tie(0);
	ios::sync_with_stdio(0);
//	freopen("game.in","r",stdin);
//	freopen("game.out","w",stdout);
	cin>>n>>X>>Y>>Z;
	fac[0]=1;
	for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod;
	ifac[N-1]=qpow(fac[N-1],mod-2);
	for(int i=N-1;i>=1;i--)ifac[i-1]=ifac[i]*i%mod;
	for(int i=1;i<N;i++)inv[i]=qpow(i,mod-2); 
	for(int i=1;i<N;i++){
		pw[i][0]=1;
		for(int j=1;j<N;j++){
			pw[i][j]=pw[i][j-1]*ifac[i]%mod;
		}
	}
	if(X==0&&Y==0&&Z==0)solve1();
	else solve2(); 
	return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 46824
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define int ll
#define ld long double
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define REP(i,j) for(int i=0;i<j;++i)
#define REPA(i,j) for(int i=1;i<=j;++i)
#define vi vector<int>
#define pii pair<int,int>
#define mt make_tuple
#define all(a) a.begin(),a.end()
using namespace std;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
inline void read(int &x){
//	short neg=1;
	x=0;
	char c=getchar();
	/*while(c<'0'||c>'9'){
		if(c=='-')neg=-1;
		c=getchar();
	}*/
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
//	x*=neg;
}
ll quick_mod(ll A,ll B){//A^B
    ll ret=1;
    A%=MOD;
    while(B){
        if(B&1)ret=ret*A%MOD;
        B>>=1;
        A=A*A%MOD;
    }
    return ret;
}
inline void chkmin(ll &x,ll y){x=min(x,y);}
inline void chkmax(ll &x,ll y){x=max(x,y);}
inline void add(ll &x,ll y){x=(x+y<MOD)?(x+y):(x+y-MOD);}
//#define add(x,y) (x=((x+(y)<MOD)?(x+(y)):(x+(y)-MOD)))
inline ll rev(ll x){return quick_mod(x,MOD-2);}
inline int lowbit(int x){return x&(-x);}
const int MAXN=2020;
int fct[MAXN],rfct[MAXN];
inline int C(int n,int m){
	if(m>n||n<0||m<0)return 0;
	return fct[n]*rfct[m]%MOD*rfct[n-m]%MOD;
}
int dp[MAXN],nln[MAXN];
int rpw[MAXN][MAXN],pw[MAXN][MAXN];

signed main(void){
//	freopen("game.in","r",stdin);
//	freopen("game.out","w",stdout);
	int N,X,Y,Z;cin>>N>>X>>Y>>Z;
	fct[0]=1;REPA(i,2000)fct[i]=fct[i-1]*i%MOD;
	rfct[2000]=rev(fct[2000]);for(int i=2000-1;i>=0;--i)rfct[i]=rfct[i+1]*(i+1)%MOD;
	REPA(i,2000){
		rpw[i][0]=1,rpw[i][1]=rev(i);
		for(int j=2;j<=2000;++j)rpw[i][j]=rpw[i][j-1]*rpw[i][1]%MOD;
		pw[i][0]=1;
		REPA(j,2000)pw[i][j]=pw[i][j-1]*i%MOD;
	}
	if(X+Y+Z==0){
		int ans=0;
		REP(i,N+1){
			if((N-i)%2==0){
				add(ans,C(N,i)*fct[N-i]%MOD*rev(quick_mod(2,(N-i)/2))%MOD*rfct[(N-i)/2]%MOD);
			}
		}
		ans=ans*quick_mod(N,N)%MOD;
		cout<<ans<<"\n";
		return 0;
	}
	int K=abs(Y-X-Z);
	dp[0]=1;
	REPA(i,N){
		if(K==0)nln[i]=1;
		else nln[i]=i/__gcd(i,K);
//		cout<<nln[i]<<"\n";
	}
//	cout<<K<<"\n";
	for(int i=1;i<=N;++i){
		int m=N/i;
		vector<int>f(m+2,0ll);
		f[0]=1;
		for(int j=1;j<=m;++j){
			if(nln[j*i]==i){
				int val=fct[j-1]*pw[i][j-1]%MOD;
				for(int k=m;k>=0;--k){
					for(int z=1,t=val,h=rfct[j];k+z*j<=m;++z,t=t*val%MOD,h=h*rfct[j]%MOD){
						add(f[k+z*j],f[k]*t%MOD*h%MOD*rfct[z]%MOD);
					}
				}
			}
		}
//		cout<<i<<":";
//		REPA(j,m)cout<<f[j]*fct[j]%MOD<<" ";cout<<"\n";
		if(i%2==1){
			REPA(j,m){
				int tmp=0;
				REP(k,j+1)if((j-k)%2==0){
					add(tmp,fct[j]*pw[i][(j-k)>>1]%MOD*rfct[k]%MOD*rpw[2][(j-k)>>1]%MOD*rfct[(j-k)>>1]%MOD);
				}
				f[j]=f[j]*tmp%MOD;
//				cout<<j<<"::"<<tmp<<" "<<fct[1]<<" "<<pw[1][0]%MOD<<" "<<rfct[1]%MOD<<" "<<rpw[2][0]%MOD<<" "<<rfct[0]%MOD<<"\n";
			}
			for(int j=N;j>=0;--j){
				for(int k=1;j+k*i<=N;++k){
					add(dp[j+k*i],dp[j]*f[k]%MOD*rpw[i][k]%MOD);
				}
			}
		}
		else{
			for(int j=N;j>=0;--j){
				for(int k=1;j+k*i<=N;++k)if(!(k&1)){
					add(dp[j+k*i],dp[j]*f[k]%MOD*rpw[i][k]%MOD*rpw[2][k>>1]%MOD*fct[k]%MOD*pw[i][k>>1]%MOD*rfct[k>>1]%MOD);
				}
			}
		}
	}
	cout<<dp[N]*fct[N]%MOD<<"\n";
	return 0;
}
/*
think twice, code once;
think once, debug forever.
*/
accuracy: 1
time_ms: 40
memory_kb: 67012
final_rank: 12

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define int ll
#define ld long double
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define REP(i,j) for(int i=0;i<j;++i)
#define REPA(i,j) for(int i=1;i<=j;++i)
#define vi vector<int>
#define pii pair<int,int>
#define mt make_tuple
#define all(a) a.begin(),a.end()
using namespace std;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
inline void read(int &x){
//	short neg=1;
	x=0;
	char c=getchar();
	/*while(c<'0'||c>'9'){
		if(c=='-')neg=-1;
		c=getchar();
	}*/
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
//	x*=neg;
}
ll quick_mod(ll A,ll B){//A^B
    ll ret=1;
    A%=MOD;
    while(B){
        if(B&1)ret=ret*A%MOD;
        B>>=1;
        A=A*A%MOD;
    }
    return ret;
}
inline void chkmin(ll &x,ll y){x=min(x,y);}
inline void chkmax(ll &x,ll y){x=max(x,y);}
inline void add(ll &x,ll y){x=(x+y<MOD)?(x+y):(x+y-MOD);}
//#define add(x,y) (x=((x+(y)<MOD)?(x+(y)):(x+(y)-MOD)))
inline ll rev(ll x){return quick_mod(x,MOD-2);}
inline int lowbit(int x){return x&(-x);}
const int MAXN=2020;
int fct[MAXN],rfct[MAXN];
inline int C(int n,int m){
	if(m>n||n<0||m<0)return 0;
	return fct[n]*rfct[m]%MOD*rfct[n-m]%MOD;
}
int dp[MAXN],nln[MAXN];
int rpw[MAXN][MAXN],pw[MAXN][MAXN];

signed main(void){
//	freopen("game.in","r",stdin);
//	freopen("game.out","w",stdout);
	int N,X,Y,Z;cin>>N>>X>>Y>>Z;
	fct[0]=1;REPA(i,N)fct[i]=fct[i-1]*i%MOD;
	rfct[N]=rev(fct[N]);for(int i=N-1;i>=0;--i)rfct[i]=rfct[i+1]*(i+1)%MOD;
	REPA(i,N){
		rpw[i][0]=1,rpw[i][1]=rev(i);
		for(int j=2;j<=N;++j)rpw[i][j]=rpw[i][j-1]*rpw[i][1]%MOD;
		pw[i][0]=1;
		REPA(j,N)pw[i][j]=pw[i][j-1]*i%MOD;
	}
	if(X+Y+Z==0){
		int ans=0;
		REP(i,N+1){
			if((N-i)%2==0){
				add(ans,C(N,i)*fct[N-i]%MOD*rev(quick_mod(2,(N-i)/2))%MOD*rfct[(N-i)/2]%MOD);
			}
		}
		ans=ans*quick_mod(N,N)%MOD;
		cout<<ans<<"\n";
		return 0;
	}
	int K=abs(Y-X-Z);
	dp[0]=1;
	REPA(i,N){
		if(K==0)nln[i]=1;
		else nln[i]=i/__gcd(i,K);
	}
//	cout<<K<<"\n";
	for(int i=1;i<=N;++i){
		int m=N/i;
		vector<int>f(m+2,0ll);
		f[0]=1;
		for(int j=1;j<=m;++j){
			if(nln[j*i]==i){
				int val=fct[j-1]*pw[i][j-1]%MOD;
				for(int k=m;k>=0;--k){
					for(int z=1,t=val,h=rfct[j];k+z*j<=m;++z,t=t*val%MOD,h=h*rfct[j]%MOD){
						add(f[k+z*j],f[k]*t%MOD*h%MOD*rfct[z]%MOD);
					}
				}
			}
		}
//		cout<<i<<":";
//		REPA(j,m)cout<<f[j]*fct[j]%MOD<<" ";cout<<"\n";
		if(i%2==1){
			REPA(j,m){
				int tmp=0;
				REP(k,j+1)if((j-k)%2==0){
					add(tmp,fct[j]*pw[i][(j-k)>>1]%MOD*rfct[k]%MOD*rpw[2][(j-k)>>1]%MOD*rfct[(j-k)>>1]%MOD);
				}
				f[j]=f[j]*tmp%MOD;
			}
			for(int j=N;j>=0;--j){
				for(int k=1;j+k*i<=N;++k){
					add(dp[j+k*i],dp[j]*f[k]%MOD*rpw[i][k]%MOD);
				}
			}
		}
		else{
			for(int j=N;j>=0;--j){
				for(int k=1;j+k*i<=N;++k)if(!(k&1)){
					add(dp[j+k*i],dp[j]*f[k]%MOD*rpw[i][k]%MOD*rpw[2][k>>1]%MOD*fct[k]%MOD*pw[i][k>>1]%MOD*rfct[k>>1]%MOD);
				}
			}
		}
	}
	cout<<dp[N]*fct[N]%MOD<<"\n";
	return 0;
}
/*
think twice, code once;
think once, debug forever.
*/
accuracy: 0.7317073170731707
time_ms: 10
memory_kb: 33268
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for (int i=(a);i<=(n);i++)
#define per(i,a,n) for (int i=(n);i>=(a);i--)
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3f
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define lowbit(i) ((i)&(-i))
#define all(x) x.begin(),x.end()
#define SZ(x) ((int)x.size())
using namespace std;
const int N = 2015, mod = 1e9 + 7;
int n, dp[N], f[N], inv[N], ifac[N], pw[N], fodd[N], feven[N];
ll X, Y, Z, O;

int main() {
	fodd[0] = feven[0] = 1;
	cin >> n >> X >> Y >> Z;

	rep(j, 1, n) {
		fodd[j] = fodd[j - 1];
		if (j >= 2) {
			fodd[j] = (fodd[j] + (ll) fodd[j - 2] * (j - 1)) % mod;
			feven[j] = (ll) feven[j - 2] * (j - 1) % mod;
		}
	}

	ifac[0] = inv[1] = 1;
	rep(i, 2, n) inv[i] = (ll) (mod - mod / i) * inv[mod % i] % mod;
	rep(i, 1, n) ifac[i] = (ll) ifac[i - 1] * inv[i] % mod;

	if (X == 0 && Y == 0 && Z == 0) {
		int ans = fodd[n];

		rep(i, 1, n) {
			ans = (ll) ans * n % mod;
		}

		cout << ans << '\n';
		return 0;
	}

	O = abs(X + Z - Y);
	dp[0] = 1;

	rep(i, 1, n) {
		memset(f, 0, sizeof f);
		f[0] = 1;
		pw[0] = 1;

		rep(j, 1, n / i) {
			if (__gcd((ll) i * j, O) == j) {
				per(k, j, n / i) {
					int w = 1;
					rep(l, 1, k / j) {
						w = (ll) w * inv[i * j] % mod;
						f[k] = (f[k] + (ll) f[k - l * j] * ifac[l] % mod * w) % mod;
					}
				}
			}

			pw[j] = (ll) pw[j - 1] * inv[i] % mod;
		}

		rep(j, 1, n) {
			fodd[j] = fodd[j - 1];
			if (j >= 2) {
				fodd[j] = (fodd[j] + (ll) fodd[j - 2] * (j - 1) % mod * i) % mod;
				feven[j] = (ll) feven[j - 2] * (j - 1) % mod * i % mod;
			}
		}

		rep(j, 1, n / i) {
			f[j] = (ll) f[j] * ((i & 1) ? fodd[j] : feven[j]) % mod;
		}

		per(k, 1, n) {
			rep(j, 1, k / i) {
				dp[k] = (dp[k] + (ll) dp[k - i * j] * f[j]) % mod;
			}
		}
	}

	int ans = dp[n];
	rep(i, 1, n) ans = (ll) ans * i % mod;
	cout << ans << '\n';
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3476
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#define rep(i,a,b) for(int i = (a); i <= (b); i++)
#define per(i,b,a) for(int i = (b); i >= (a); i--)
#define N 2022
#define ll long long
#define mod 1000000007
#define pow ppppow
using namespace std;

int n;
ll X, Y, Z, P;
ll C[N][N], pow[N][N], w[N][N], ffact[N], fact[N], invf[N], inv[N];
ll f[N][N], g[N][N], dp[N][N];
vector<int> len[N];

ll gcd(ll a, ll b){ return b ? gcd(b, a%b) : a; }

void init(){
    inv[0] = fact[0] = invf[0] = ffact[0] = C[0][0] = 1;
    rep(i,1,n){
        inv[i] = i == 1 ? 1 : (mod-mod/i) * inv[mod%i] % mod;
        fact[i] = fact[i-1] * i % mod, invf[i] = invf[i-1] * inv[i] % mod;
        ffact[i] = i == 1 ? 1 : ffact[i-2] * (i-1) % mod;
        pow[i][0] = C[i][0] = 1;
        rep(j,1,n) pow[i][j] = pow[i][j-1] * i % mod;
        rep(j,1,i) C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
    }
    rep(k,1,n) rep(m,0,n/k){
        if(k%2 == 0) w[k][m] = m%2 ? 0 : pow[k][m/2] * ffact[m] % mod;
        else rep(i,0,m) if(i%2 == 0)
            (w[k][m] += C[m][i] * pow[k][i/2] % mod * ffact[i]) %= mod;
    }
}

int main(){
    cin>>n>>X>>Y>>Z;
    P = X+Z-Y;
    if(P < 0) P *= -1;
    init();

    if(X == 0 && Y == 0 && Z == 0){
        cout<< w[1][n] * pow[n][n] % mod <<endl;
        return 0;
    }

    rep(i,1,n) len[i / gcd(i, P)].push_back(i);
    rep(j,1,n){
        int siz = len[j].size();
        rep(k,0,n/j) rep(l,0,siz) g[k][l] = 0;
        g[0][0] = 1;
        rep(k,0,n/j) rep(l,0,siz) if(g[k][l]){
            if(l == siz){ f[j][k] = g[k][l]; continue; }
            int cur = len[j][l];
            ll div = 1;
            rep(i,0,(n/j-k)/(cur/j)) 
                (g[k+i*(cur/j)][l+1] += g[k][l] * fact[j*k+cur*i] % mod * invf[j*k] % mod * div % mod * invf[i]) %= mod,
                (div *= inv[cur]) %= mod;
        }
    }
    dp[0][1] = 1;
    rep(i,0,n) rep(j,1,n) if(dp[i][j]) rep(k,0,(n-i)/j) 
        (dp[i+j*k][j+1] += dp[i][j] * C[i+j*k][j*k] % mod * f[j][k] % mod * w[j][k]) %= mod;
    cout<< dp[n][n+1] <<endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 107412
final_rank: 14

code_snippet: #include<iostream>
#include<fstream>
#include<vector>
#define rep(i,a,b) for(int i = (a); i <= (b); i++)
#define per(i,b,a) for(int i = (b); i >= (a); i--)
#define N 2022
#define ll long long
#define mod 1000000007
#define pow ppppow
using namespace std;

int n;
ll X, Y, Z, P;
ll C[N][N], pow[N][N], w[N][N], ffact[N], fact[N], invf[N], inv[N];
ll f[N][N], g[N][N], dp[N][N];
vector<int> len[N];

ll gcd(ll a, ll b){ return b ? gcd(b, a%b) : a; }

void init(){
    inv[0] = inv[1] = 1;
    rep(i,2,n) inv[i] = (mod-mod/i) * inv[mod%i] % mod;
    fact[0] = invf[0] = 1;
    rep(i,1,n) fact[i] = fact[i-1] * i % mod, invf[i] = invf[i-1] * inv[i] % mod;
    ffact[0] = ffact[1] = 1;
    rep(i,2,n) ffact[i] = ffact[i-2] * (i-1) % mod;
    rep(i,1,n){
        pow[i][0] = 1;
        rep(j,1,n) pow[i][j] = pow[i][j-1] * i % mod;
    }
    C[0][0] = 1;
    rep(i,1,n){
        C[i][0] = 1;
        rep(j,1,i) C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
    }
    rep(k,1,n){
        rep(m,0,n/k){
            if(k%2 == 0){
                if(m%2 == 0) w[k][m] = pow[k][m/2] * ffact[m] % mod;
                else w[k][m] = 0;
            } else rep(i,0,m) if(i%2 == 0)
                (w[k][m] += C[m][i] * pow[k][i/2] % mod * ffact[i]) %= mod;
        }
    }
}

int main(){
    cin>>n>>X>>Y>>Z;
    P = X+Z-Y;
    if(P < 0) P *= -1;
    init();

    if(X == 0 && Y == 0 && Z == 0){
        ll ans = 0;
        rep(i,0,n) if(i % 2 == 0)
            (ans += C[n][i] * ffact[i]) %= mod;
        rep(i,1,n) (ans *= n) %= mod;
        cout<< ans <<endl;
        return 0;
    }

    rep(i,1,n) len[i / gcd(i, P)].push_back(i);
    rep(j,1,n){
        int siz = len[j].size();
        rep(k,0,n/j) rep(l,0,siz) g[k][l] = 0;
        g[0][0] = 1;
        rep(k,0,n/j) rep(l,0,siz) if(g[k][l]){
            if(l == siz){ f[j][k] = g[k][l]; continue; }
            int cur = len[j][l];
            ll div = 1;
            rep(i,0,(n/j-k)/(cur/j)) 
                (g[k+i*(cur/j)][l+1] += g[k][l] * fact[j*k+cur*i] % mod * invf[j*k] % mod * div % mod * invf[i]) %= mod,
                (div *= inv[cur]) %= mod;
        }
    }
    dp[0][1] = 1;
    rep(i,0,n) rep(j,1,n) if(dp[i][j]) rep(k,0,(n-i)/j) 
        (dp[i+j*k][j+1] += dp[i][j] * C[i+j*k][j*k] % mod * f[j][k] % mod * w[j][k]) %= mod;
    cout<< dp[n][n+1] <<endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 107304
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e9+7;
int myp(int x,int t){
	int a=1;
	for(;t;t>>=1,x=(ll)x*x%M)if(t&1)a=(ll)a*x%M;
	return a;
}
ll X,Y,Z;int n,f[2004][2004];
vector<int>v[2004];
int iv[2004];
int g[2004],ng[2004];
int h[2004];
int main(){
	scanf("%d%lld%lld%lld",&n,&X,&Y,&Z),X=abs(X+Z-Y);
	iv[0]=1;for(int i=1;i<=n;i++)v[i/__gcd(X,(ll)i)].push_back(i),iv[i]=myp(i,M-2);
	for(int i=1;i<=n;i++){
		f[i][0]=1,f[i][1]=(i&1);
		for(int j=2;j<=n;j++)
			f[i][j]=((ll)f[i][j-2]*(j-1)*i+(ll)f[i][j-1]*(i&1))%M;
	}
	if(!X&&!Y){
		int cur=1;for(int i=1;i<=n;i++)cur=(ll)cur*n%M;
		printf("%lld\n",(ll)cur*f[1][n]%M);return 0;
	}
	h[0]=1;
	for(int i=1;i<=n;i++)if(!v[i].empty()){
		memset(g,0,sizeof(g));g[0]=1;int m=n/i;
		for(auto x:v[i]){
			memcpy(ng,g,sizeof(g));int t=x/i;
			for(int j=1,mul=1;j*t<=m;j++){
				mul=(ll)mul*iv[x]%M*iv[j]%M;
				for(int k=0;k+j*t<=m;k++)
					(ng[k+j*t]+=(ll)mul*g[k]%M)%=M;
			}
			memcpy(g,ng,sizeof(g));
		}
		for(int j=n;j;j--)
			for(int k=1;i*k<=j;k++)
				(h[j]+=(ll)h[j-i*k]*f[i][k]%M*g[k]%M)%=M;
	}
	int ans=h[n];
	for(int i=1;i<=n;i++)ans=(ll)ans*i%M;
	printf("%d\n",ans);
}
accuracy: 1
time_ms: 10
memory_kb: 11764
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e9+7;
int myp(int x,int t){
	int a=1;
	for(;t;t>>=1,x=(ll)x*x%M)if(t&1)a=(ll)a*x%M;
	return a;
}
ll X,Y,Z;int n,f[2004][2004];
vector<int>v[2004];
int iv[2004];
int g[2004],ng[2004];
int h[2004];
int main(){
//	freopen("game.in","r",stdin);
//	freopen("game.out","w",stdout);
	scanf("%d%lld%lld%lld",&n,&X,&Y,&Z),X=abs(X+Z-Y);
	iv[0]=1;for(int i=1;i<=n;i++)v[i/__gcd(X,(ll)i)].push_back(i),iv[i]=myp(i,M-2);
	for(int i=1;i<=n;i++){
		f[i][0]=1,f[i][1]=(i&1);
		for(int j=2;j<=n;j++)
			f[i][j]=((ll)f[i][j-2]*(j-1)*i+(ll)f[i][j-1]*(i&1))%M;
	}
//	cout<<f[5][1]<<"\n";
	if(!X&&!Y){
		int cur=1;for(int i=1;i<=n;i++)cur=(ll)cur*n%M;
		printf("%lld\n",(ll)cur*f[1][n]%M);return 0;
	}
	h[0]=1;
	for(int i=1;i<=n;i++)if(!v[i].empty()){
//		if(i<2)continue;
		memset(g,0,sizeof(g));g[0]=1;int m=n/i;
//		cout<<iv[3]<<" "<<m<<"\n";
		for(auto x:v[i]){
//			cout<<i<<" "<<x<<"\n";
			memcpy(ng,g,sizeof(g));int t=x/i;
			for(int j=1,mul=1;j*t<=m;j++){
				mul=(ll)mul*iv[x]%M*iv[j]%M;
				for(int k=0;k+j*t<=m;k++)
					(ng[k+j*t]+=(ll)mul*g[k]%M)%=M;
			}
			memcpy(g,ng,sizeof(g));
		}
//		cout<<g[1]<<"\n";
//		cout<<g[2]<<"\n";
//		cout<<g[5]<<"\n";
		for(int j=n;j;j--)
			for(int k=1;i*k<=j;k++)
				(h[j]+=(ll)h[j-i*k]*f[i][k]%M*g[k]%M)%=M;
//		for(int j=0;j<=n;j++)cout<<h[j]<<" ";puts("");
//		int tmp=h[n];
//		for(int j=1;j<=n;j++)tmp=(ll)tmp*j%M;
//		cout<<tmp;
//		return 0;
	}
	int ans=h[n];
	for(int i=1;i<=n;i++)ans=(ll)ans*i%M;
	printf("%d\n",ans);
}
accuracy: 1
time_ms: 10
memory_kb: 11764
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF push_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
#define lc (x<<1)
#define rc ((x<<1)|1)
#define sz(x) ((int)x.size())
using namespace std;
const int mod=1e9+7;
int n,X,Y,Z;
P<int,int> p[2005];
V<int> v[2005];
int dp[2005],d[2005];
int f[2005],inv[2005],finv[2005],val[2005],val2[2005];
void add(int &x,int y){
	x+=y;
	if(x>=mod)x-=mod;
}
int POW(int x,int y){
	int re=1;
	while(y){
		if(y&1)re=re*x%mod;
		x=x*x%mod;
		y/=2;
	}
	RE re;
}
int C(int x,int y){
	if(x<0||y<0||x<y)RE 0;
	RE f[x]*finv[y]%mod*finv[x-y]%mod;
}
void pref(){
	f[0]=f[1]=inv[1]=finv[0]=finv[1]=1;
	FOR(i,2,2002){
		f[i]=f[i-1]*i%mod;
		inv[i]=mod-inv[mod%i]*(mod/i)%mod;
		finv[i]=finv[i-1]*inv[i]%mod;
	}
}
signed main(){
//	freopen("game.in","r",stdin);
//	freopen("game.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>X>>Y>>Z;
	if(!X&&!Y&&!Z){
		int mul=POW(n,n);
		dp[1]=dp[2]=1;
		rep(i,1,n){
			add(dp[i+1],dp[i]);
			add(dp[i+2],dp[i]*(i+1)%mod);
		}
		cout<<dp[n]*mul%mod<<'\n';RE 0;
	}
	X=abs(X+Z-Y);
	pref();
	FOR(i,1,n){
		int t=__gcd(X,i);
		p[i]=MP(i/t,t);
		v[i/t].PB(t);
	}
	dp[0]=1;
	FOR(i,1,n)if(!v[i].empty()){
		FILL(d,0);
		d[0]=1;
		rep(j,0,n/i)if(d[j]){
			for(auto u:v[i]){
				if(j+u<=n/i)add(d[j+u],C((j+u)*i-1,u*i-1)*d[j]%mod*f[u*i-1]%mod);
			}
		}
		val2[0]=1;
		for(int j=2;j<=n/i;j++)val2[j]=val2[j-2]*(j-1)%mod*i%mod;
		if(!(i&1)){
			for(int j=n;j>=0;j--){
				FOR(k,1,n/i)if(d[k]&&j+k*i<=n)add(dp[j+k*i],val2[k]*dp[j]%mod*finv[k*i]%mod*d[k]%mod);
			}
		}else{
			val[0]=1;
			FOR(j,1,n/i){
				val[j]=0;
				FOR(k,0,j)add(val[j],C(j,k)*val2[j-k]%mod);
			}
			for(int j=n;j>=0;j--){
				FOR(k,1,n/i)if(d[k]&&j+k*i<=n)add(dp[j+k*i],val[k]*dp[j]%mod*finv[k*i]%mod*d[k]%mod);
			}
		}
	}
	cout<<dp[n]*f[n]%mod<<'\n';
	RE 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3628
final_rank: 2