Problem:
Problem
順序木とは、各ノードに一つの整数の書かれた根付き木であって、以下の条件をみたすもののことです。
任意のノードに書かれた整数は $0$ より大きい
二つのノードが兄弟なら、書かれた整数は異なる
あるノードに書かれた整数 $k$ が $1$ より大きいなら、そのノードの兄弟であって $k-1$ が書かれたものが存在する
また、二つの順序木 $O,P$ が同型であるとは、以下の条件を満たすことをいいます。
$O$ と $P$ の根の次数が等しい
$O$ の根の子 $o$ と $P$ の根の子 $p$ に書かれた整数が等しいなら、$o$ を根とした部分木と $p$ を根とした部分木が順序木として同型である
順序木のノード $v$ の点数を以下のように定義します。
$v$ が根なら、$v$ の子供の数
そうでないなら、$v$ の親の点数 + $v$ の子供の数 - $v$ に書かれた整数
以下の条件をみたす順序木の個数を $998244353$ で割ったあまりを求めてください。
全ての整数 $i$ に対して、$0 \leq i \leq N-1$ なら点数が $i$ のノードの個数が $A_i$ である
全ての整数 $i$ に対して、$N \leq i$ なら点数が $i$ のノードの個数が $0$ である
Input
入力は以下の形式で与えられる。
$N$
$A_0$ $A_1$ $\ldots$ $A_{N-1}$
Constraints
入力は以下の条件を満たす。
$1 \leq N \leq 10^6$
$1 \leq A_i \leq 10^6$
入力は全て整数である
Output
答えを一行に出力せよ。
Sample Input 1
3
2 2 2
Sample Output 1
0
Sample Input 2
8
1 1 1 1 1 1 1 1
Sample Output 2
1
Sample Input 3
10
1 5 3 7 9 1000000 1000000 98735 2 6
Sample Output 3
951998726

Submitted solutions:

code_snippet: // AOJ #3082 Points on Tree
// 2025.4.20

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

#define gc() getchar_unlocked()

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

ll mod_pow(ll a, ll e = MOD - 2) {
    ll r = 1;
    a %= MOD;
    while (e > 0) {
        if (e & 1) r = r * a % MOD;
        a = a * a % MOD;
        e >>= 1;
    }
    return r;
}

int main(){
    int N = Cin();
    vector<ll> A(N);
    for(int i = 0; i < N; i++) A[i] = Cin();

    if (A[0] != 1) { cout << 0 << endl; return 0; }

    ll max_n = 0;
    for(int i = 1; i < N; i++){
        ll n = A[i-1] - 1 + A[i];
        if (n > max_n) max_n = n;
    }

    vector<ll> fact(max_n+1), ifact(max_n+1);
    fact[0] = 1;
    for(ll i = 1; i <= max_n; i++) fact[i] = fact[i-1] * i % MOD;
    ifact[max_n] = mod_pow(fact[max_n]);
    for(ll i = max_n; i > 0; i--) ifact[i-1] = ifact[i] * i % MOD;

    auto comb = [&](ll n, ll k){
        if (k < 0 || k > n) return 0LL;
        return fact[n] * ifact[k] % MOD * ifact[n-k] % MOD;
    };

    ll ans = 1;
    for(int i = 1; i < N; i++){
        ll n = A[i-1] - 1 + A[i];
        ll k = A[i-1] - 1;
        ans = ans * comb(n, k) % MOD;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 42064
final_rank: 2

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

constexpr long long MOD = 998244353 ;

class binomial_coefficients {
	long long MAX_VAL;
	vector<long long> fac, mmi;

public:

	binomial_coefficients(){
	}
	
	binomial_coefficients(long long num){
		init(num);
	}
	
	~binomial_coefficients(){
		
	}
	
	void init(long long num){
		MAX_VAL = num+1; 
		fac.resize(MAX_VAL);
		mmi.resize(MAX_VAL);
		
		factorial_mod();
		modular_multiplicatibe_inverse();
	}
	
	void factorial_mod(){
		 fac[0] = 1;
		for(long long i = 1; i < MAX_VAL; fac[i] %= MOD, i++)
			fac[i] = fac[i - 1] * (i % MOD);
	}
	
	long long power(long long x, long long n){
		long long ans = 1;
		for(;n;n >>= 1, x *= x, ans %= MOD, x %= MOD)
			if(n&1)ans*=x;
		return ans % MOD;
	}
	
	void exgcd(long long a, long long b, long long &x, long long &y){
		if(b == 0){
			x = 1;
			y = 0;
			return ;
		}
		exgcd(b, a % b, y, x);
		y -= a / b * x;
	}
	
	void modular_multiplicatibe_inverse(){
		long long x, y;  
		exgcd(fac[MAX_VAL - 1], MOD, x, y);
		mmi[MAX_VAL-1] = (x%MOD + MOD) % MOD;
		// mmi[MAX_VAL-1] = power(fac[MAX_VAL-1], MOD-2);
		for(long long i = MAX_VAL - 2; i >= 0; mmi[i]%=MOD, i--)
			mmi[i] = mmi[i + 1] * ((i + 1) % MOD);
	}
	
	long long combination(long long n, long long r){
		return n < r ? 0 :fac[n] * (mmi[r] * mmi[n-r] % MOD) % MOD;
	}
};

int main(){
	constexpr int MAX = 2e6+10;
	binomial_coefficients BC;
	long long N, ans = 1;
	vector<int> A;
	
	cin>>N;
	
	BC.init(MAX);
	A.resize(N);
	
	
	
	for(int i = 0; i < N; i++){
		cin>>A[i];
	}
	
	if(A[0] != 1) ans = 0;
	
	for(int i = 1; i < N; i++){
		ans *= BC.combination(A[i] + A[i-1] - 1, A[i]);
		ans %= MOD;
	}
	
	cout<<ans<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 37888
final_rank: 7

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 21;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}


void solve() {
	int n; cin >> n;
	vector<int> a(n);
	rep(i, n)cin >> a[i];
	modint ans = 1;
	if (a[0] != 1)ans = 0;
	rep(i, n - 1) {
		ans *= comb(a[i] - 1 + a[i + 1], a[i] - 1);
	}
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 39540
final_rank: 3

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long long INF = 1e18;
const ll mod = 998244353;
vector<ll> inv, FactorialInv, Factorial;
ll beki(ll a, ll b){
    ll ret = 1 % mod;
    a %= mod;
    while(b) {
        if(b & 1LL) ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret;
}
void init_combination(ll MAX){
    Factorial.resize(MAX + 1);
    FactorialInv.resize(MAX + 1);
    inv.resize(MAX + 1);
    Factorial[0] = 1;
    inv[0] = 1;
    for(int i = 1; i <= MAX; i++){
        Factorial[i] = Factorial[i - 1] * i % mod;
    }
    FactorialInv[MAX] = beki(Factorial[MAX], mod - 2);
    for(ll i = MAX - 1; i >= 0; i--) {
        FactorialInv[i] = FactorialInv[i+1] * (i+1) % mod;
    }
    for(int i = 1; i <= MAX; i++) {
        inv[i] = FactorialInv[i] * Factorial[i-1] % mod;
    }
}
ll combination(ll a, ll b){
    if((a == b) || (b == 0)){
        return 1;
    }
    if(a < b) return 0;
    if(b < 0) return 0;
    ll ans = Factorial[a] * FactorialInv[b] % mod;
    ans = ans * FactorialInv[a - b] % mod;
    return ans;
}

ll N;
ll A[1050000];

int main() {
    init_combination(3000000);
    cin >> N;
    for(int i = 0; i < N; i++) cin >> A[i];
    if(A[0] != 1) {
        cout << 0 << endl;
        return 0;
    }
    ll ans = 1;
    for(int i = 1; i < N; i++) {
        ll tmp = combination(A[i-1] - 1 + A[i], A[i-1] - 1);
        ans = ans * tmp % mod;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 81500
final_rank: 12

code_snippet: //Let's join Kaede Takagaki Fan Club !!
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define all(x) x.begin(),x.end()
template<class T>
void dmp(T a){
	rep(i,a.size()) cout << a[i] << " ";
	cout << endl;
}
template<class T>
bool chmax(T&a, T b){
	if(a < b){
		a = b;
		return 1;
	}
	return 0;
}
template<class T>
bool chmin(T&a, T b){
	if(a > b){
		a = b;
		return 1;
	}
	return 0;
}
template<class T>
void g(T &a){
	cin >> a;
}
template<class T>
void o(const T &a,bool space=false){
	cout << a << (space?' ':'\n');
}
//ios::sync_with_stdio(false);
const ll mod = 998244353;
template<class T>
void add(T&a,T b){
	a+=b;
	if(a >= mod) a-=mod;
}


ll rui[200005];
ll modpow(ll x,ll n){
	ll res=1;
	while(n>0){
		if(n&1) res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	}
	return res;
}
ll F[2000005],R[2000005];
void make(){
	F[0] = 1;
	for(int i=1;i<2000005;i++) F[i] = F[i-1]*i%mod;
	for(int i=0;i<2000005;i++) R[i] = modpow(F[i],mod-2);
}
ll C(int a,int b){
	return F[a]*R[b]%mod*R[a-b]%mod;
}
int n, a[1000005];

int main(){
	cin >> n;
	repn(i, n) cin >> a[i];
	if(a[1] != 1){
		cout << 0 << endl;
		return 0;
	}
	ll ans = 1;
	make();
	for(int i=2;i<=n;i++){
		ans = ans * C(a[i]+a[i-1]-1, a[i]) % mod;
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 390
memory_kb: 38576
final_rank: 10

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}
 
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}

template <unsigned int mod>
class ModInt {
private:
    unsigned int v;
    static unsigned int norm(const unsigned int& x){ return x < mod ? x : x - mod; }
    static ModInt make(const unsigned int& x){ ModInt m; return m.v = x, m; }
    static ModInt inv(const ModInt& x){ return make(inverse(x.v, mod)); }
    static unsigned int inverse(int a, int m){
        int u[] = {a, 1, 0}, v[] = {m, 0, 1}, t;
        while(*v){
            t = *u / *v;
            swap(u[0] -= t * v[0], v[0]), swap(u[1] -= t * v[1], v[1]), swap(u[2] -= t * v[2], v[2]);
        }
        return (u[1] % m + m) % m;
    }

public:
    ModInt() : v{0}{}
    ModInt(const long long val) : v{norm(val % mod + mod)} {}
    ModInt(const ModInt<mod>& n) : v{n()} {}
    explicit operator bool() const noexcept { return v != 0; }
    bool operator!() const noexcept { return !static_cast<bool>(*this); }
    ModInt& operator=(const ModInt& n){ return v = n(), (*this); }
    ModInt& operator=(const long long val){ return v = norm(val % mod + mod), (*this); }
    ModInt operator+() const { return *this; }
    ModInt operator-() const { return v == 0 ? make(0) : make(mod - v); }
    ModInt operator+(const ModInt& val) const { return make(norm(v + val())); }
    ModInt operator-(const ModInt& val) const { return make(norm(v + mod - val())); }
    ModInt operator*(const ModInt& val) const { return make((long long)v * val() % mod); }
    ModInt operator/(const ModInt& val) const { return *this * inv(val); }
    ModInt& operator+=(const ModInt& val){ return *this = *this + val; }
    ModInt& operator-=(const ModInt& val){ return *this = *this - val; }
    ModInt& operator*=(const ModInt& val){ return *this = *this * val; }
    ModInt& operator/=(const ModInt& val){ return *this = *this / val; }
    ModInt operator+(const long long val) const { return ModInt{v + val}; }
    ModInt operator-(const long long val) const { return ModInt{v - val}; }
    ModInt operator*(const long long val) const { return ModInt{(long long)v * (val % mod)}; }
    ModInt operator/(const long long val) const { return ModInt{(long long)v * inv(val)}; }
    ModInt& operator+=(const long long val){ return *this = *this + val; }
    ModInt& operator-=(const long long val){ return *this = *this - val; }
    ModInt& operator*=(const long long val){ return *this = *this * val; }
    ModInt& operator/=(const long long val){ return *this = *this / val; }
    bool operator==(const ModInt& val) const { return v == val.v; }
    bool operator!=(const ModInt& val) const { return !(*this == val); }
    bool operator==(const long long val) const { return v == norm(val % mod + mod); }
    bool operator!=(const long long val) const { return !(*this == val); }
    unsigned int operator()() const { return v; }
    friend ModInt operator+(const long long val, const ModInt& n) { return n + val; }
    friend ModInt operator-(const long long val, const ModInt& n) { return ModInt{val - n()}; }
    friend ModInt operator*(const long long val, const ModInt& n) { return n * val; }
    friend ModInt operator/(const long long val, const ModInt& n) { return ModInt{val} / n; }
    friend bool operator==(const long long val, const ModInt& n) { return n == val; }
    friend bool operator!=(const long long val, const ModInt& n) { return !(val == n); }
    friend istream& operator>>(istream& is, ModInt& n){
        unsigned int v;
        return is >> v, n = v, is;
    }
    friend ostream& operator<<(ostream& os, const ModInt& n){ return (os << n()); }
    friend ModInt mod_pow(ModInt x, long long n){
        ModInt ans = 1;
        while(n){
            if(n & 1) ans *= x;
            x *= x, n >>= 1;
        }
        return ans;
    }
};

#define MOD 998244353
using mod = ModInt<MOD>;

#define MAX_N 2000010
mod inv[MAX_N],fac[MAX_N],finv[MAX_N];

void make()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i=2;i<MAX_N;i++){
        inv[i] = MOD - inv[MOD % i] * (MOD / i);
        fac[i] = fac[i-1] * i;
        finv[i] = finv[i-1] * inv[i];
    }
}

mod comb(int a, int b)
{
    if(a<b) return 0;
    return fac[a] * finv[b] * finv[a-b];
}

int main(){
    make();
    int n;
    cin >> n;
    vector<int> a(n);
    rep(i,n) cin >> a[i];
    mod res = 1;
    if(a[0]!=1){
        cout << 0 << endl;
        return 0;
    }
    for(int i=1;i<n;i++){
        res *= comb(a[i]+a[i-1]-1,a[i-1]-1);
    }
    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 30332
final_rank: 4

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

using namespace std;
#define INFS (1LL<<28)
#define DEKAI 1000000007
//#define MOD 1000000007
#define lp(i,n) for(int i=0;i<n;i++)
#define lps(i,n) for(int i=1;i<=n;i++)
#define all(c) begin(c), end(c)

//#define int long long

namespace {
#define __DECLARE__(C)						\
  template <typename T>						\
  std::ostream &operator<<(std::ostream &, const C<T> &);

#define __DECLAREM__(C)						\
  template <typename T, typename U>				\
  std::ostream &operator<<(std::ostream &, const C<T, U> &);

  __DECLARE__(std::vector)
  __DECLARE__(std::deque)
  __DECLARE__(std::set)
  __DECLARE__(std::stack)
  __DECLARE__(std::queue)
  __DECLARE__(std::priority_queue)
  __DECLARE__(std::unordered_set)
  __DECLAREM__(std::map)
  __DECLAREM__(std::unordered_map)

  template <typename T, typename U>
  std::ostream &operator<<(std::ostream &, const std::pair<T, U> &);
  template <typename... T>
  std::ostream &operator<<(std::ostream &, const std::tuple<T...> &);
  template <typename T, std::size_t N>
  std::ostream &operator<<(std::ostream &, const std::array<T, N> &);

  template <typename Tuple, std::size_t N>
  struct __TuplePrinter__ {
    static void print(std::ostream &os, const Tuple &t) {
      __TuplePrinter__<Tuple, N - 1>::print(os, t);
      os << ", " << std::get<N - 1>(t);
    }
  };

  template <typename Tuple>
  struct __TuplePrinter__<Tuple, 1> {
    static void print(std::ostream &os, const Tuple &t) { os << std::get<0>(t); }
  };

  template <typename... T>
  std::ostream &operator<<(std::ostream &os, const std::tuple<T...> &t) {
    os << '(';
    __TuplePrinter__<decltype(t), sizeof...(T)>::print(os, t);
    os << ')';
    return os;
  }

  template <typename T, typename U>
  std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &v) {
    return os << '(' << v.first << ", " << v.second << ')';
  }

#define __INNER__				\
  os << '[';					\
  for (auto it = begin(c); it != end(c);) {	\
    os << *it;					\
    os << (++it != end(c) ? ", " : "");		\
  }						\
  return os << ']';

  template <typename T, std::size_t N>
  std::ostream &operator<<(std::ostream &os, const std::array<T, N> &c) {
    __INNER__
      }

#define __DEFINE__(C)                                           \
  template <typename T>						\
  std::ostream &operator<<(std::ostream &os, const C<T> &c) {	\
    __INNER__							\
      }

#define __DEFINEM__(C)							\
  template <typename T, typename U>					\
  std::ostream &operator<<(std::ostream &os, const C<T, U> &c) {	\
    __INNER__								\
      }

#define __DEFINEW__(C, M1, M2)                                  \
  template <typename T>						\
  std::ostream &operator<<(std::ostream &os, const C<T> &c) {	\
    std::deque<T> v;						\
    for (auto d = c; !d.empty(); d.pop()) v.M1(d.M2());		\
    return os << v;						\
  }

  __DEFINE__(std::vector)
  __DEFINE__(std::deque)
  __DEFINE__(std::set)
  __DEFINEW__(std::stack, push_front, top)
  __DEFINEW__(std::queue, push_back, front)
  __DEFINEW__(std::priority_queue, push_front, top)
  __DEFINE__(std::unordered_set)
  __DEFINEM__(std::map)
  __DEFINEM__(std::unordered_map)
}

#define pii pair<int,int>
#define ll long long
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// modint
template <signed M, unsigned T>
struct mod_int {
  constexpr static signed MODULO = M;
  constexpr static unsigned TABLE_SIZE = T;

  signed x;

  mod_int() : x(0) {}

  mod_int(long long y) : x(static_cast<signed>(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO)) {}

  mod_int(int y) : x(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO) {}

  mod_int &operator+=(const mod_int &rhs) {
    if ((x += rhs.x) >= MODULO) x -= MODULO;
    return *this;
  }

  mod_int &operator-=(const mod_int &rhs) {
    if ((x += MODULO - rhs.x) >= MODULO) x -= MODULO;
    return *this;
  }

  mod_int &operator*=(const mod_int &rhs) {
    x = static_cast<signed>(1LL * x * rhs.x % MODULO);
    return *this;
  }

  mod_int &operator/=(const mod_int &rhs) {
    x = static_cast<signed>((1LL * x * rhs.inv().x) % MODULO);
    return *this;
  }

  mod_int operator-() const { return mod_int(-x); }

  mod_int operator+(const mod_int &rhs) const { return mod_int(*this) += rhs; }

  mod_int operator-(const mod_int &rhs) const { return mod_int(*this) -= rhs; }

  mod_int operator*(const mod_int &rhs) const { return mod_int(*this) *= rhs; }

  mod_int operator/(const mod_int &rhs) const { return mod_int(*this) /= rhs; }

  bool operator<(const mod_int &rhs) const { return x < rhs.x; }

  mod_int inv() const {
    assert(x != 0);
    if (x <= static_cast<signed>(TABLE_SIZE)) {
      if (_inv[1].x == 0) prepare();
      return _inv[x];
    } else {
      signed a = x, b = MODULO, u = 1, v = 0, t;
      while (b) {
	t = a / b;
	a -= t * b;
	std::swap(a, b);
	u -= t * v;
	std::swap(u, v);
      }
      return mod_int(u);
    }
  }

  mod_int pow(long long t) const {
    assert(!(x == 0 && t == 0));
    mod_int e = *this, res = mod_int(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1) res *= e;
    return res;
  }

  mod_int fact() {
    if (_fact[0].x == 0) prepare();
    return _fact[x];
  }

  mod_int inv_fact() {
    if (_fact[0].x == 0) prepare();
    return _inv_fact[x];
  }

  mod_int choose(mod_int y) {
    assert(y.x <= x);
    return this->fact() * y.inv_fact() * mod_int(x - y.x).inv_fact();
  }

  static mod_int _inv[TABLE_SIZE + 1];

  static mod_int _fact[TABLE_SIZE + 1];

  static mod_int _inv_fact[TABLE_SIZE + 1];

  static void prepare() {
    _inv[1] = 1;
    for (int i = 2; i <= (int)TABLE_SIZE; ++i) {
      _inv[i] = 1LL * _inv[MODULO % i].x * (MODULO - MODULO / i) % MODULO;
    }
    _fact[0] = 1;
    for (unsigned i = 1; i <= TABLE_SIZE; ++i) {
      _fact[i] = _fact[i - 1] * int(i);
    }
    _inv_fact[TABLE_SIZE] = _fact[TABLE_SIZE].inv();
    for (int i = (int)TABLE_SIZE - 1; i >= 0; --i) {
      _inv_fact[i] = _inv_fact[i + 1] * (i + 1);
    }
  }
};

template <int M, unsigned F>
std::ostream &operator<<(std::ostream &os, const mod_int<M, F> &rhs) {
  return os << rhs.x;
}

template <int M, unsigned F>
std::istream &operator>>(std::istream &is, mod_int<M, F> &rhs) {
  long long s;
  is >> s;
  rhs = mod_int<M, F>(s);
  return is;
}

template <int M, unsigned F>
mod_int<M, F> mod_int<M, F>::_inv[TABLE_SIZE + 1];

template <int M, unsigned F>
mod_int<M, F> mod_int<M, F>::_fact[TABLE_SIZE + 1];

template <int M, unsigned F>
mod_int<M, F> mod_int<M, F>::_inv_fact[TABLE_SIZE + 1];

template <int M, unsigned F>
bool operator==(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) {
  return lhs.x == rhs.x;
}

template <int M, unsigned F>
bool operator!=(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) {
  return !(lhs == rhs);
}

const int MF = 1000010;
const int MOD = 998244353;

using mint = mod_int<MOD, MF>;

mint binom(int n, int r) { return (r < 0 || r > n || n < 0) ? 0 : mint(n).choose(r); }

mint fact(int n) { return mint(n).fact(); }

mint inv_fact(int n) { return mint(n).inv_fact(); }

const ll mod = 998244353;
#define int long long
#define double long double

template <typename Int, Int MOD, int N>
struct comb_util {
  std::array<Int, N + 1> fc, ifc;

  comb_util() {
    fc[0] = 1;
    for (int i = 1; i <= N; i++) fc[i] = fc[i - 1] * i % MOD;
    ifc[N] = inv(fc[N]);
    for (int i = N - 1; i >= 0; i--) ifc[i] = ifc[i + 1] * (i + 1) % MOD;
  }

  Int fact(Int n) { return fc[n]; }

  Int inv_fact(Int n) { return ifc[n]; }

  Int inv(Int n) { return pow(n, MOD - 2); }

  Int pow(Int n, Int a) {
    Int res = 1, exp = n;
    for (; a; a /= 2) {
      if (a & 1) res = res * exp % MOD;
      exp = exp * exp % MOD;
    }
    return res;
  }

  Int perm(Int n, Int r) {
    if (r < 0 || n < r)
      return 0;
    else
      return fc[n] * ifc[n - r] % MOD;
  }

  Int binom(Int n, Int r) {
    if (n < 0 || r < 0 || n < r) return 0;
    return fc[n] * ifc[r] % MOD * ifc[n - r] % MOD;
  }

  Int homo(Int n, Int r) {
    if (n < 0 || r < 0) return 0;
    return r == 0 ? 1 : binom(n + r - 1, r);
  }
};

using comb = comb_util<long long, mod, 3000000>;

signed main(){
  int n;
  cin>>n;
  vector<int> v(n);
  comb cm;
  lp(i,n){
    cin>>v[i];
  }
  mint ans = 1;
  if(v[0]!=1){
    ans = 0;
  }
  for(int i=1;i<n;i++){
    ans*=cm.homo(v[i-1],v[i]);
  }
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 69584
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
//const ll MOD=1000000007;
const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}


template<long long int mod=1000000007>
struct Mod_Int{
    typedef long long int ll;
    typedef pair<ll,ll> pll;
    typedef Mod_Int<mod> M;
    ll a;
    
    ll mod_pow(ll a,ll x){
        a%=mod;
        ll ans=1;
        for(int i=0;i<63;i++){
            if(x>>i&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
        }
        return ans;
    }
    
    pll Ex_gcd(ll a,ll b){
        if(b==0){return {1,0};}
        pll ret=Ex_gcd(b,a%b);
        ret.F-=a/b*ret.S;
        return {ret.S,ret.F};
    }
    
    ll prime_R(ll a){
        return mod_pow(a,mod-2);
    }
    
    ll R(ll a){
        ll ret=Ex_gcd(a,mod).F;
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    Mod_Int(ll A=1):a(A){
        a%=mod;
        if(a<0){a+=mod;}
    }
    
    Mod_Int(const M &b):a(b.a){}
    
    M & operator += (const M &b){
        a+=b.a;
        if(a>=mod){a-=mod;}
        return *this;
    }
    
    M operator + (const M &b) const {
        M c=*this;
        return c+=b;
    }
    
    M & operator -= (const M &b){
        a-=b.a;
        if(a<0){a+=mod;}
        return *this;
    }
    
    M operator - (const M &b) const {
        M c=*this;
        return c-=b;
    }
    
    M & operator *= (const M &b){
        (a*=b.a)%=mod;
        return *this;
    }
    
    M operator * (const M &b) const {
        M c=*this;
        return c*=b;
    }
    
    M & operator /= (const M &b){
        (a*=R(b.a))%=mod;
        return *this;
    }
    
    M operator / (const M &b) const {
        M c=*this;
        return c/=b;
    }
    
    M & mod_pow_equal(ll x){
        ll ans=1;
        while(x>0){
            if(x&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
            x>>=1;
        }
        a=ans;
        return *this;
    }
    
    M mod_pow(ll x){
        M c(a);
        return c.mod_pow_equal(x);
    }
    
    bool operator == (const M &b) const {return a==b.a;}
    
    bool operator != (const M &b) const {return a!=b.a;}
    
    bool operator <= (const M &b) const {return a<=b.a;}
    
    bool operator < (const M &b) const {return a<b.a;}
    
    bool operator > (const M &b) const {return a>b.a;}
    
    bool operator >= (const M &b) const {return a>=b.a;}
    
    M & operator = (const M &b){
        a=b.a;
        return *this;
    }
    
    M & operator = (const ll &b){
        (a=b)%=mod;
        if(a<0){a+=mod;}
        return *this;
    }
};

template<long long MOD>istream & operator >> (istream &i,Mod_Int<MOD> &A){ll a; cin>>a; A=Mod_Int<MOD>(a); return i;}
template<long long MOD>ostream & operator << (ostream &i,const Mod_Int<MOD> &A){i<<A.a; return i;}

class comb{
private:
    ll mod;
    ll mx;
    vector<ll> F;
    vector<ll> FR;
    
public:
    comb(ll mod=1000000007,ll mx=100000):mod(mod),mx(mx),F(mx+1,1),FR(mx+1,1){
        mk_F();
    }
    
    ll mod_pow(ll a,ll x){
        a%=mod;
        ll ans=1;
        while(x>0){
            if(x&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
            x>>=1;
        }
        return ans;
    }
    
    pll Ex_gcd(ll a,ll b){
        if(b==0){return {1,0};}
        pll ret=Ex_gcd(b,a%b);
        ret.F-=a/b*ret.S;
        return {ret.S,ret.F};
    }
    
    ll prime_R(ll a){
        return mod_pow(a,mod-2);
    }
    
    ll R(ll a){
        ll ret=Ex_gcd(a,mod).F;
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    void mk_F(){
        for(ll i=1;i<=mx;i++){F[i]=F[i-1]*i%mod; FR[i]=R(F[i]);}
    }
    
    ll c(ll n,ll k){
        if(n<k || k<0 || n<0){return 0;}
        if(n==k || k==0){return 1;}
        return F[n]*FR[n-k]%mod*FR[k]%mod;
    }
    
    //mod must be prime
    ll Lucas_C(ll n,ll m){
        ll ret=1;
        while(n>0 || m>0){
            ret*=c(n%mod,m%mod);
            ret%=mod;
            n/=mod; m/=mod;
        }
        return ret;
    }
    
    ll Stirling(ll n,ll k){
        ll ret=0;
        for(ll i=1;i<=k;i++){
            if((k-i)%2){ret-=c(k,i)*mod_pow(i,n)%mod;}
            else{ret+=c(k,i)*mod_pow(i,n)%mod;}
            ret%=mod;
        }
        ret*=R(F[k]);
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    ll Bell(ll n,ll k){
        ll ret=0;
        for(ll i=1;i<=k;i++){ret+=Stirling(n,i); ret%=mod;}
        return ret;
    }
};


comb C(MOD,2e6);

using Int=Mod_Int<MOD>;

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll N;
  cin>>N;
  vector<ll> A(N);
  cin>>A;
  Int ans=(A[0]==1?1:0);
  for(int i=0;i+1<N;i++){ans*=C.c(A[i+1]+A[i]-1,A[i]-1);}
  cout<<ans<<endl;
  

  return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 42072
final_rank: 14

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

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

struct Combination {
  int mod; // e.g. 1000000007
  vector<int> fact; // factorial
  vector<int> invf; // inverse factorial
  vector<vector<int> > part; // partition number

  /*
    constructor : O(sz+log(mod))   
    make factorial table (fact) and inverse factorial table (invf)
  */
  Combination(int sz, int mod) : fact(sz+1), invf(sz+1), mod(mod) {
    fact[0] = 1;
    for ( int i = 1; i < (int)fact.size(); i++ ) {
      fact[i] = fact[i-1]*i%mod;
    }
    invf[sz] = inv(fact[sz]);
    for ( int i = sz-1; i >= 0; i-- ) {
      invf[i] = invf[i+1]*(i+1)%mod;
    }
  }

  int pow(int x, int n) const {
    int ret = 1;
    while ( n > 0 ) {
      if ( n & 1 ) (ret *= x) %= mod;
      (x *= x) %= mod;
      n >>= 1;
    }
    return ret;
  }

  int inv(int x) const {
    return pow(x, mod - 2);
  }

  /*
    permutation
  */
  int P(int n, int r) const {
    if ( r < 0 || n < r ) return (0);
    return fact[n]*invf[n-r]%mod;    
  }

  /*
    combination
  */
  int C(int n, int r) const {
    if ( r < 0 || n < r ) return (0);    
    return fact[n]*invf[r]%mod*invf[n-r]%mod;    
  }  

  /*
    combination with repetition
  */
  int H(int n, int r) const {
    if ( n < 0 || r < 0 ) return 0;
    if ( n == 0 && r == 0 ) return 1;
    return C(n+r-1, n);    
  }

  /*
    stirling number
  */
  int S(int n, int r) const {
    int ret = 0;
    for ( int i = 1; i <= r; i++ ) {
      int add = C(r, i)*pow(i, n)%mod;      
      if ( (r-i)&1 ) ret += mod-add;
      else ret += add;
      ret %= mod;      
    }
    (ret *= invf[r]) %= mod;
    return ret;
  }

  /*
    bell number
  */
  int B(int n, int r) const {
    int ret = 0;
    for ( int i = 1; i <= r; i++ ) {
      (ret += S(n, i)) %= mod;      
    }
    return ret;
  }

  /*
    calc partition number
    return and make partition number table (part)
  */
  vector<vector<int> > built_part(int n, int r) {
    part = vector<vector<int> >(n+1, vector<int>(r+1, 0));
    part[0][0] = 1;
    for ( int i = 0; i <= n; i++ ) {
      for ( int j = 1; j <= r; j++ ) {
	if ( i-j >= 0 ) {
	  (part[i][j] = part[i][j-1]+part[i-j][j]) %= mod;	  
	} else {
	  part[i][j] = part[i][j-1];
	}
      }
    }
    return part;    
  }

  /*
    TODO 
    make built_part() that make only part[i][i]
    https://twitter.com/kirika_comp/status/953482654787149824
    http://d.hatena.ne.jp/DEGwer/20170829
    http://mathworld.wolfram.com/BellNumber.html
  }    
  */
};

const int MOD = 998244353;

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int N;
  cin >> N;

  vector<int> A(N);
  REP(i, N) cin >> A[i];

  if ( A[0] != 1 ) {
    cout << 0 << endl;
    return 0;
  }

  Combination comb(2e6, MOD);  
  int ans = 1;
  for ( int i = 1; i < N; i++ ) {
    ans *= comb.C(A[i-1]+A[i]-1, A[i]);
    ans %= MOD;    
  }

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 41892
final_rank: 5

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

constexpr long long MOD = 998244353 ;

class binomial_coefficients {
	long long MAX_VAL;
	vector<long long> fac, mmi;

public:

	binomial_coefficients(){
	}
	
	binomial_coefficients(long long num){
		init(num);
	}
	
	~binomial_coefficients(){
		
	}
	
	void init(long long num){
		MAX_VAL = num+1; 
		fac.resize(MAX_VAL);
		mmi.resize(MAX_VAL);
		
		factorial_mod();
		modular_multiplicatibe_inverse();
	}
	
	void factorial_mod(){
		 fac[0] = 1;
		for(long long i = 1; i < MAX_VAL; fac[i] %= MOD, i++)
			fac[i] = fac[i - 1] * (i % MOD);
	}
	
	long long power(long long x, long long n){
		long long ans = 1;
		for(;n;n >>= 1, x *= x, ans %= MOD, x %= MOD)
			if(n&1)ans*=x;
		return ans % MOD;
	}
	
	void exgcd(long long a, long long b, long long &x, long long &y){
		if(b == 0){
			x = 1;
			y = 0;
			return ;
		}
		exgcd(b, a % b, y, x);
		y -= a / b * x;
	}
	
	void modular_multiplicatibe_inverse(){
		long long x, y;  
		exgcd(fac[MAX_VAL - 1], MOD, x, y);
		mmi[MAX_VAL-1] = (x%MOD + MOD) % MOD;
		// mmi[MAX_VAL-1] = power(fac[MAX_VAL-1], MOD-2);
		for(long long i = MAX_VAL - 2; i >= 0; mmi[i]%=MOD, i--)
			mmi[i] = mmi[i + 1] * ((i + 1) % MOD);
	}
	
	long long combination(long long n, long long r){
		return n < r ? 0 :fac[n] * (mmi[r] * mmi[n-r] % MOD) % MOD;
	}
};

int main(){
	constexpr int MAX = 2e6+10;
	binomial_coefficients BC;
	long long N, ans = 1;
	vector<int> A;
	
	cin>>N;
	
	BC.init(MAX);
	A.resize(N);
	
	
	
	for(int i = 0; i < N; i++){
		cin>>A[i];
	}
	
	if(A[0] != 1) ans = 0;
	
	for(int i = 1; i < N; i++){
		ans *= BC.combination(A[i] + A[i-1] - 1, A[i]);
		ans %= MOD;
	}
	
	cout<<ans<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 37956
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


template<typename T,T MOD = 1000000007>
struct Mint{
  static constexpr T mod = MOD;
  T v;
  Mint():v(0){}
  Mint(signed v):v(v){}
  Mint(long long t){v=t%MOD;if(v<0) v+=MOD;}

  Mint pow(long long k){
    Mint res(1),tmp(v);
    while(k){
      if(k&1) res*=tmp;
      tmp*=tmp;
      k>>=1;
    }
    return res;
  }

  static Mint add_identity(){return Mint(0);}
  static Mint mul_identity(){return Mint(1);}

  Mint inv(){return pow(MOD-2);}

  Mint& operator+=(Mint a){v+=a.v;if(v>=MOD)v-=MOD;return *this;}
  Mint& operator-=(Mint a){v+=MOD-a.v;if(v>=MOD)v-=MOD;return *this;}
  Mint& operator*=(Mint a){v=1LL*v*a.v%MOD;return *this;}
  Mint& operator/=(Mint a){return (*this)*=a.inv();}

  Mint operator+(Mint a) const{return Mint(v)+=a;}
  Mint operator-(Mint a) const{return Mint(v)-=a;}
  Mint operator*(Mint a) const{return Mint(v)*=a;}
  Mint operator/(Mint a) const{return Mint(v)/=a;}

  Mint operator-() const{return v?Mint(MOD-v):Mint(v);}

  bool operator==(const Mint a)const{return v==a.v;}
  bool operator!=(const Mint a)const{return v!=a.v;}
  bool operator <(const Mint a)const{return v <a.v;}

  static Mint comb(long long n,int k){
    Mint num(1),dom(1);
    for(int i=0;i<k;i++){
      num*=Mint(n-i);
      dom*=Mint(i+1);
    }
    return num/dom;
  }
};
template<typename T,T MOD> constexpr T Mint<T, MOD>::mod;
template<typename T,T MOD>
ostream& operator<<(ostream &os,Mint<T, MOD> m){os<<m.v;return os;}


template<typename M>
class Enumeration{
private:
  static vector<M> fact,finv,invs;
public:
  static void init(int n){
    n=min<decltype(M::mod)>(n,M::mod-1);

    int m=fact.size();
    if(n<m) return;

    fact.resize(n+1,1);
    finv.resize(n+1,1);
    invs.resize(n+1,1);

    if(m==0) m=1;
    for(int i=m;i<=n;i++) fact[i]=fact[i-1]*M(i);
    finv[n]=M(1)/fact[n];
    for(int i=n;i>=m;i--) finv[i-1]=finv[i]*M(i);
    for(int i=m;i<=n;i++) invs[i]=finv[i]*fact[i-1];
  }

  static M Fact(int n){
    init(n);
    return fact[n];
  }
  static M Finv(int n){
    init(n);
    return finv[n];
  }
  static M Invs(int n){
    init(n);
    return invs[n];
  }

  static M C(int n,int k){
    if(n<k||k<0) return M(0);
    init(n);
    return fact[n]*finv[n-k]*finv[k];
  }

  static M P(int n,int k){
    if(n<k||k<0) return M(0);
    init(n);
    return fact[n]*finv[n-k];
  }

  // put n identical balls into k distinct boxes
  static M H(int n,int k){
    if(n<0||k<0) return M(0);
    if(!n&&!k) return M(1);
    init(n+k-1);
    return C(n+k-1,k);
  }
};
template<typename M>
vector<M> Enumeration<M>::fact=vector<M>();
template<typename M>
vector<M> Enumeration<M>::finv=vector<M>();
template<typename M>
vector<M> Enumeration<M>::invs=vector<M>();


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}

//INSERT ABOVE HERE
signed main(){
  using M = Mint<int, 998244353>;
  using E = Enumeration<M>;
  E::init(2e6);

  int n;
  cin>>n;
  vector<int> as(n);
  for(int i=0;i<n;i++) cin>>as[i];
  if(as[0]!=1) drop(0);

  M ans{1};
  for(int i=0;i+1<n;i++)
    ans*=E::H(as[i],as[i+1]);
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 30436
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
//const ll MOD=1000000007;
const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}


template<long long int mod=1000000007>
struct Mod_Int{
    typedef long long int ll;
    typedef pair<ll,ll> pll;
    typedef Mod_Int<mod> M;
    ll a;
    
    ll mod_pow(ll a,ll x){
        a%=mod;
        ll ans=1;
        for(int i=0;i<63;i++){
            if(x>>i&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
        }
        return ans;
    }
    
    pll Ex_gcd(ll a,ll b){
        if(b==0){return {1,0};}
        pll ret=Ex_gcd(b,a%b);
        ret.F-=a/b*ret.S;
        return {ret.S,ret.F};
    }
    
    ll prime_R(ll a){
        return mod_pow(a,mod-2);
    }
    
    ll R(ll a){
        ll ret=Ex_gcd(a,mod).F;
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    Mod_Int(ll A=1):a(A){
        a%=mod;
        if(a<0){a+=mod;}
    }
    
    Mod_Int(const M &b):a(b.a){}
    
    M & operator += (const M &b){
        a+=b.a;
        if(a>=mod){a-=mod;}
        return *this;
    }
    
    M operator + (const M &b) const {
        M c=*this;
        return c+=b;
    }
    
    M & operator -= (const M &b){
        a-=b.a;
        if(a<0){a+=mod;}
        return *this;
    }
    
    M operator - (const M &b) const {
        M c=*this;
        return c-=b;
    }
    
    M & operator *= (const M &b){
        (a*=b.a)%=mod;
        return *this;
    }
    
    M operator * (const M &b) const {
        M c=*this;
        return c*=b;
    }
    
    M & operator /= (const M &b){
        (a*=R(b.a))%=mod;
        return *this;
    }
    
    M operator / (const M &b) const {
        M c=*this;
        return c/=b;
    }
    
    M & mod_pow_equal(ll x){
        ll ans=1;
        while(x>0){
            if(x&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
            x>>=1;
        }
        a=ans;
        return *this;
    }
    
    M mod_pow(ll x){
        M c(a);
        return c.mod_pow_equal(x);
    }
    
    bool operator == (const M &b) const {return a==b.a;}
    
    bool operator != (const M &b) const {return a!=b.a;}
    
    bool operator <= (const M &b) const {return a<=b.a;}
    
    bool operator < (const M &b) const {return a<b.a;}
    
    bool operator > (const M &b) const {return a>b.a;}
    
    bool operator >= (const M &b) const {return a>=b.a;}
    
    M & operator = (const M &b){
        a=b.a;
        return *this;
    }
    
    M & operator = (const ll &b){
        (a=b)%=mod;
        if(a<0){a+=mod;}
        return *this;
    }
};

template<long long MOD>istream & operator >> (istream &i,Mod_Int<MOD> &A){ll a; cin>>a; A=Mod_Int<MOD>(a); return i;}
template<long long MOD>ostream & operator << (ostream &i,const Mod_Int<MOD> &A){i<<A.a; return i;}

class comb{
private:
    ll mod;
    ll mx;
    vector<ll> F;
    vector<ll> FR;
    
public:
    comb(ll mod=1000000007,ll mx=100000):mod(mod),mx(mx),F(mx+1,1),FR(mx+1,1){
        mk_F();
    }
    
    ll mod_pow(ll a,ll x){
        a%=mod;
        ll ans=1;
        while(x>0){
            if(x&1){ans*=a; ans%=mod;}
            a*=a;
            a%=mod;
            x>>=1;
        }
        return ans;
    }
    
    pll Ex_gcd(ll a,ll b){
        if(b==0){return {1,0};}
        pll ret=Ex_gcd(b,a%b);
        ret.F-=a/b*ret.S;
        return {ret.S,ret.F};
    }
    
    ll prime_R(ll a){
        return mod_pow(a,mod-2);
    }
    
    ll R(ll a){
        ll ret=Ex_gcd(a,mod).F;
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    void mk_F(){
        for(ll i=1;i<=mx;i++){F[i]=F[i-1]*i%mod; FR[i]=R(F[i]);}
    }
    
    ll c(ll n,ll k){
        if(n<k || k<0 || n<0){return 0;}
        if(n==k || k==0){return 1;}
        return F[n]*FR[n-k]%mod*FR[k]%mod;
    }
    
    //mod must be prime
    ll Lucas_C(ll n,ll m){
        ll ret=1;
        while(n>0 || m>0){
            ret*=c(n%mod,m%mod);
            ret%=mod;
            n/=mod; m/=mod;
        }
        return ret;
    }
    
    ll Stirling(ll n,ll k){
        ll ret=0;
        for(ll i=1;i<=k;i++){
            if((k-i)%2){ret-=c(k,i)*mod_pow(i,n)%mod;}
            else{ret+=c(k,i)*mod_pow(i,n)%mod;}
            ret%=mod;
        }
        ret*=R(F[k]);
        ret%=mod;
        if(ret<0){ret+=mod;}
        return ret;
    }
    
    ll Bell(ll n,ll k){
        ll ret=0;
        for(ll i=1;i<=k;i++){ret+=Stirling(n,i); ret%=mod;}
        return ret;
    }
};


comb C(MOD,2e6);

using Int=Mod_Int<MOD>;

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll N;
  cin>>N;
  vector<ll> A(N);
  cin>>A;
  Int ans=(A[0]==1?1:0);
  for(int i=0;i+1<N;i++){ans*=C.c(A[i+1]+A[i]-1,A[i]-1);}
  cout<<ans<<endl;
  

  return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 42000
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
const ll MOD=1000000007;
//const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}

ll mod_pow(ll a,ll x,ll mod){
  ll ret=1;
  while(x>0){
    if(x&1){(ret*=a)%=mod;}
    (a*=a)%=mod;
    x>>=1;
  }
  return ret;
}

//sum_{i=0}^{x} a^i \bmod mod
ll cul(ll a,ll x,ll mod){
  a%=mod;
  ll k=1,ret=0,s=1,l=a;
  for(ll i=1;x>0;i<<=1){
    if(x&i){(ret+=s*k%mod)%=mod; (k*=l)%=mod; x^=i;}
    (s+=l*s%mod)%=mod;
    (l*=l)%=mod;
  }
  return ret;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll H,W,N,Q;
  cin>>H>>W>>N>>Q;
  ll a=1,vx=0,vy=0;
  for(int i=0;i<N;i++){
    ll x,y,m;
    cin>>x>>y>>m;
    a+=m;
    (vx-=x*m%H)%=H;
    (vy-=y*m%W)%=W;
  }
  if(vx<0){vx+=H;}
  if(vy<0){vy+=W;}
  for(int i=0;i<Q;i++){
    ll x,y,k,X,Y;
    cin>>x>>y>>k;
    X=mod_pow(a,k,H)*x%H;
    Y=mod_pow(a,k,W)*y%W;
    X+=cul(a,k,H)*vx%H;
    Y+=cul(a,k,W)*vy%W;
    X%=H;
    Y%=W;
    cout<<X<<" "<<Y<<endl;
  }
  


  return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 3464
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

//INSERT ABOVE HERE

const int LOG = 62;
const int MAX = 1e5 + 100;

int ny[LOG][MAX];
int nx[LOG][MAX];

signed main(){
  int h,w,n,q;
  cin>>h>>w>>n>>q;

  vector<int> as(n),bs(n),ms(n);
  for(int i=0;i<n;i++) cin>>as[i]>>bs[i]>>ms[i];

  vector<int> cs(q),ds(q);
  vector<long long> ks(q);
  for(int i=0;i<q;i++) cin>>cs[i]>>ds[i]>>ks[i];

  int sy=0,ty=0,sx=0,tx=0;
  for(int i=0;i<n;i++){
    sy+=ms[i];
    sx+=ms[i];
    ty+=(long long)as[i]*ms[i]%h;
    tx+=(long long)bs[i]*ms[i]%w;
    sy%=h;ty%=h;
    sx%=w;tx%=w;
  }

  for(int i=0;i<h;i++)
    ny[0][i]=(i+(long long)i*sy+(h-ty))%h;
  for(int j=0;j<w;j++)
    nx[0][j]=(j+(long long)j*sx+(w-tx))%w;

  for(int t=0;t+1<LOG;t++){
    for(int i=0;i<h;i++) ny[t+1][i]=ny[t][ny[t][i]];
    for(int j=0;j<w;j++) nx[t+1][j]=nx[t][nx[t][j]];
  }

  for(int i=0;i<q;i++){
    int y=cs[i],x=ds[i];
    for(int t=0;t<LOG;t++){
      if((ks[i]>>t)&1){
        y=ny[t][y];
        x=nx[t][x];
      }
    }
    cout<<y<<" "<<x<<"\n";
  }
  cout<<flush;
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 52580
final_rank: 6

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1000000007; 

#define a first.first
#define b first.second
#define m second

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);
	
	int H, W, N, Q;
	int summ = 0;
	vector<pair<pair<int,int>,int>> in;
	vector<int> tableh, tablew;
	vector<vector<int>> tableh2, tablew2;
	
	cin>>H>>W>>N>>Q;
	
	in.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>in[i].a>>in[i].b>>in[i].m;
		
		summ += in[i].m;
	}
	
	tableh.resize(H);
	tablew.resize(W);
	
	tableh2.resize(65, vector<int>(H));
	tablew2.resize(65, vector<int>(W));
	
	for(int i = 0; i < N; i++){
		tableh[0] += (H - (in[i].a * in[i].m) % H) % H;
		tableh[0] %= H;
		
		tablew[0] += (W - (in[i].b * in[i].m) % W) % W;
		tablew[0] %= W;
	}
	
	for(int i = 1; i < H; i++){
		tableh[i] = tableh[i-1] + summ % H;
		tableh[i] %= H;
	}
	
	for(int i = 1; i < W; i++){
		tablew[i] = tablew[i-1] + summ % W;
		tablew[i] %= W;
	}
	
	for(int i = 0; i < H; i++){
		tableh[i] += i;
		tableh[i] %= H;
		
		tableh2[0][i] = tableh[i];
	}
	
	for(int i = 0; i < W; i++){
		tablew[i] += i;
		tablew[i] %= W;
		
		tablew2[0][i] = tablew[i];
	}
	
	for(int i = 1; i < tableh2.size(); i++){
		for(int j = 0; j < H; j++){
			tableh2[i][j] = tableh2[i-1][tableh2[i-1][j]];
		}
	}
	
	for(int i = 1; i < tablew2.size(); i++){
		for(int j = 0; j < W; j++){
			tablew2[i][j] = tablew2[i-1][tablew2[i-1][j]];
		}
	}
	
	for(int i = 0; i < Q; i++){
		int c, d, k;
		int y = 0, x = 0;
		
		cin>>c>>d>>k;
		
		y = c, x = d;
		
		for(int j = 62; j >= 0; j--){
			if(k&(1ll<<j)) {
				y = tableh2[j][y];
			}
		}
		
		for(int j = 62; j >= 0; j--){
			if(k&(1ll<<j)) {
				x = tablew2[j][x];
			}
		}
		
		cout<<y<<" "<<x<<endl;
	}
	
	
	return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 99268
final_rank: 15