Submission #50457769


Source Code Expand

#include<iostream>
#include<map>
#include<vector>
struct mint{
    static constexpr int  m = 998244353;
    int x;
    mint() : x(0){}
    mint(long long x_):x(x_ % m){if (x < 0) x += m;}
    int val(){return x;}
    mint &operator+=(mint b){if ((x += b.x) >= m) x -= m; return *this;}
    mint &operator-=(mint b){if ((x -= b.x) < 0) x += m; return *this;}
    mint &operator*=(mint b){x= (long long)(x) * b.x % m; return *this;}
    mint pow(long long e) const {
        mint r = 1,b =*this;
        while (e){
            if (e & 1) r *= b;
            b *= b;
            e >>= 1;
        }
        return r;
    }
    mint inv(){return pow(m - 2);}
    mint &operator/=(mint b){return *this *= b.pow(m - 2);}
    friend mint operator+(mint a, mint b){return a += b;}
    friend mint operator-(mint a, mint b){return a -= b;}
    friend mint operator/(mint a, mint b){return a /= b;}
    friend mint operator*(mint a, mint b){return a *= b;}
    friend bool operator==(mint a, mint b){return a.x == b.x;}
    friend bool operator!=(mint a, mint b){return a.x != b.x;}
};


namespace po167{
template<class T>
struct Binomial{
    std::vector<T> fact_vec, fact_inv_vec;
    void extend(int m = -1){
        int n = fact_vec.size();
        if (m == -1) m = n * 2;
        if (n >= m) return;
        fact_vec.resize(m);
        fact_inv_vec.resize(m);
        for (int i = n; i < m; i++){
            fact_vec[i] = fact_vec[i - 1] * T(i);
        }
        fact_inv_vec[m - 1] = T(1) / fact_vec[m - 1];
        for (int i = m - 1; i > n; i--){
            fact_inv_vec[i - 1] = fact_inv_vec[i] * T(i);
        }
    }
    Binomial(int MAX = 2){
        fact_vec.resize(1, T(1));
        fact_inv_vec.resize(1, T(1));
        extend(MAX + 1);
    }

    T fact(int i){
        if (i < 0) return 0;
        while (int(fact_vec.size()) <= i) extend();
        return fact_vec[i];
    }
    T invfact(int i){
        if (i < 0) return 0;
        while (int(fact_inv_vec.size()) <= i) extend();
        return fact_inv_vec[i];
    }
    T C(int a, int b){
        if (a < b || b < 0) return 0;
        return fact(a) * invfact(b) * invfact(a - b);
    }
    T invC(int a, int b){
        if (a < b || b < 0) return 0;
        return fact(b) * fact(a - b) *invfact(a);
    }
    T P(int a, int b){
        if (a < b || b < 0) return 0;
        return fact(a) * invfact(a - b);
    }
    T inv(int a){
        if (a < 0) return inv(-a) * T(-1);
        if (a == 0) return 1;
        return fact(a - 1) * invfact(a);
    }
};
}

int solve_arc146_e(int N, std::vector<int> A){
    po167::Binomial<mint> B(200200);
    std::map<std::pair<int, int>, mint> dp;
    dp[{0, 0}] = 1;
    for (int i = 0; i < N; i++){
        std::map<std::pair<int, int>, mint> n_dp;
        for (auto tmp: dp){
            int l_indeg = tmp.first.first;
            int l_outdeg = l_indeg;
            int t = tmp.first.second;
            if (t == 1) l_outdeg--;
            if (t == 2) l_outdeg++;
            if (l_indeg < 0 || l_outdeg < 0) continue;

            if (i != 0){
                // 連結性を保ち続ける
                if (l_indeg == 0 && t % 3 == 0) continue;

                // 同じ辺を区別しないようにする
                tmp.second *= B.invfact(l_indeg);
                tmp.second *= B.invfact(l_outdeg);
            }

            for (int k = 0; k < 4; k++) if ((k & t) == 0 ){
                int r_indeg = A[i] - l_indeg;
                int r_outdeg = A[i] - l_outdeg;
                if(k & 1) r_indeg--;
                if(k & 2) r_outdeg--;
                mint val = tmp.second;

                // 全域木の数だけ乗算する
                if ((k & 2) == 0){
                    if (t & 2) val *= l_outdeg;
                    else val *= r_outdeg;
                }

                // 自分の出次は相手の入次
                if (val != 0) n_dp[{r_outdeg, k + t}] += val;
            }
        }
        std::swap(dp, n_dp);
    }
    mint ans = dp[{0, 3}];

    // prod (outdeg - 1)!
    for (int i = 0; i < N; i++){
        ans *= B.fact(A[i] - 1);
    }
    return ans.val();
}

int main(){
    int N;
    std::cin >> N;
    std::vector<int> A(N);
    for (int i = 0; i < N; i++) std::cin >> A[i];
    std::cout << solve_arc146_e(N, A) << "\n";
}

Submission Info

Submission Time
Task E - Simple Speed
User potato167
Language C++ 17 (gcc 12.2)
Score 800
Code Size 4437 Byte
Status AC
Exec Time 105 ms
Memory 6452 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 800 / 800
Status
AC × 3
AC × 73
Set Name Test Cases
Sample example_00.txt, example_01.txt, example_02.txt
All example_00.txt, example_01.txt, example_02.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt, test_56.txt, test_57.txt, test_58.txt, test_59.txt, test_60.txt, test_61.txt, test_62.txt, test_63.txt, test_64.txt, test_65.txt, test_66.txt, test_67.txt, test_68.txt, test_69.txt
Case Name Status Exec Time Memory
example_00.txt AC 3 ms 4652 KiB
example_01.txt AC 3 ms 4696 KiB
example_02.txt AC 3 ms 4748 KiB
test_00.txt AC 15 ms 4996 KiB
test_01.txt AC 99 ms 6268 KiB
test_02.txt AC 75 ms 5796 KiB
test_03.txt AC 50 ms 5580 KiB
test_04.txt AC 31 ms 5264 KiB
test_05.txt AC 46 ms 5180 KiB
test_06.txt AC 54 ms 5560 KiB
test_07.txt AC 38 ms 5180 KiB
test_08.txt AC 93 ms 6064 KiB
test_09.txt AC 49 ms 5528 KiB
test_10.txt AC 11 ms 4736 KiB
test_11.txt AC 86 ms 6056 KiB
test_12.txt AC 88 ms 6072 KiB
test_13.txt AC 14 ms 5024 KiB
test_14.txt AC 76 ms 5924 KiB
test_15.txt AC 7 ms 4720 KiB
test_16.txt AC 9 ms 4740 KiB
test_17.txt AC 64 ms 5800 KiB
test_18.txt AC 41 ms 5272 KiB
test_19.txt AC 14 ms 5072 KiB
test_20.txt AC 74 ms 5708 KiB
test_21.txt AC 74 ms 5708 KiB
test_22.txt AC 30 ms 5176 KiB
test_23.txt AC 50 ms 5656 KiB
test_24.txt AC 102 ms 6332 KiB
test_25.txt AC 65 ms 5916 KiB
test_26.txt AC 64 ms 5792 KiB
test_27.txt AC 9 ms 4772 KiB
test_28.txt AC 90 ms 5976 KiB
test_29.txt AC 47 ms 5656 KiB
test_30.txt AC 3 ms 4868 KiB
test_31.txt AC 3 ms 4644 KiB
test_32.txt AC 3 ms 4700 KiB
test_33.txt AC 3 ms 4864 KiB
test_34.txt AC 3 ms 4672 KiB
test_35.txt AC 3 ms 4644 KiB
test_36.txt AC 102 ms 6232 KiB
test_37.txt AC 105 ms 6264 KiB
test_38.txt AC 104 ms 6244 KiB
test_39.txt AC 100 ms 6312 KiB
test_40.txt AC 104 ms 6240 KiB
test_41.txt AC 103 ms 6320 KiB
test_42.txt AC 101 ms 6236 KiB
test_43.txt AC 103 ms 6300 KiB
test_44.txt AC 101 ms 6296 KiB
test_45.txt AC 104 ms 6272 KiB
test_46.txt AC 102 ms 6232 KiB
test_47.txt AC 104 ms 6324 KiB
test_48.txt AC 103 ms 6256 KiB
test_49.txt AC 103 ms 6452 KiB
test_50.txt AC 103 ms 6240 KiB
test_51.txt AC 104 ms 6392 KiB
test_52.txt AC 104 ms 6448 KiB
test_53.txt AC 104 ms 6276 KiB
test_54.txt AC 103 ms 6268 KiB
test_55.txt AC 101 ms 6336 KiB
test_56.txt AC 42 ms 5772 KiB
test_57.txt AC 30 ms 5432 KiB
test_58.txt AC 10 ms 5004 KiB
test_59.txt AC 58 ms 6064 KiB
test_60.txt AC 25 ms 5172 KiB
test_61.txt AC 17 ms 5068 KiB
test_62.txt AC 23 ms 5464 KiB
test_63.txt AC 6 ms 4700 KiB
test_64.txt AC 13 ms 5268 KiB
test_65.txt AC 63 ms 6328 KiB
test_66.txt AC 64 ms 6392 KiB
test_67.txt AC 99 ms 6332 KiB
test_68.txt AC 63 ms 6244 KiB
test_69.txt AC 99 ms 6280 KiB