ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AGC025 B] RGB Coloring
    문제 풀이/AtCoder 2023. 1. 30. 17:32

    난이도: 1739

     

    태그

    더보기
    • Combinatorics (조합론)
      • \( _{n}C_{r} \mod p \) \( (n, r \le p) \) in \( O(N) \) Precomputation & \( O(1) \) Query

     

    풀이

    1. 색깔을 칠하는 방식에 대해

    더보기

    문제에서 말한대로, 각 층에는 4가지 중 하나의 색깔을 칠할 수 있습니다.

     

    하지만 4가지 색깔은 생각하기 어려우니까, \( A \)점의 색깔과 \( B \)점의 색깔 2가지만 고려해봅시다.

    \( A+B \)점은 두 색깔을 동시에 사용하는 경우로, \( 0 \)점은 아무 색깔도 사용하지 않는 경우입니다.

     

    이렇게 보면 색 \( A \)와 색 \( B \)는 독립적입니다.

    풀어서 말하자면, 어떤 층에 \( A \)를 칠했는지와는 관계없이 \( B \)를 칠하든 말든을 선택할 수 있다는 거죠.

     

    2. 색깔을 칠하는 방식에 대해 2

    더보기

    모든 층에 대해 점수는 동일한 방식으로 적용되므로, 각각의 색을 사용한 횟수만 알고 있으면

    탑 전체의 점수를 알 수 있게 됩니다.

     

    3. 그럼 각 색깔을 사용한 횟수만 고려해보자.

    더보기

    \( A \)를 사용한 횟수를 \( c_{A} \), \( B \)를 사용한 횟수를 \( c_{B} \)라고 해봅시다.

    그럼 탑의 점수는 \( A \cdot c_{A} + B \cdot c_{B} \)가 됩니다.

     

    그런데, \( 0 \le c_{A}, c_{B} \le N \)입니다.

    또한, \( c_{A} \)가 고정되면, \( K = A \cdot c_{A} + B \cdot c_{B} \)이므로 \( c_{B} = \frac{K - A \cdot c_{A}}{B} \)가 됩니다.

    즉, \( c_{A} \)가 고정되면 \( c_{B} \)도 고정됩니다.

     

    그러니, \( 0 \le c_{A} \le N \)에 대해 돌려보면서, 이에 맞는 \( c_{B} \)를 찾아보고, 이 때의 경우의 수를 구해봅시다.

     

    4. 색깔을 사용한 횟수가 고정될 때, 가능한 경우의 수

    더보기

    어떤 색깔을 \( C \)회 사용하는 경우의 수는 \( _{N}C_{C} \)회가 됩니다.

     

    (1번)에서 본 바와 같이, 두 색깔은 독립적으로 적용시킬 수 있으므로,

    가능한 경우의 수는 \( _{N}C_{c_A} \times _{N}C_{c_B} \)회가 됩니다.

     

    코드

    더보기

    (4번)을 \( 0 \le c_{A} \le N \)에 대해 돌려주면서, 경우의 수를 더해주면 됩니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    const ll mod = 998244353;
     
    const int N = 300000;
    ll fac[300020], inv[300020];
    ll fpow(ll mul, ll bit){ ll res = 1;
        while (bit){
            if (bit&1){ res = res*mul % mod; }
            mul = mul*mul % mod; bit >>= 1;
        }
        return res;
    }
    inline ll finv(ll x){ return fpow(x, mod-2); }
     
    inline ll ncr(int n, int r){
        if (0 > r || r > n){ return 0; }
        return fac[n] *inv[r] %mod *inv[n-r] %mod;
    }
     
    void Main(){
        fac[0= 1for (int i = 1; i <= N; i++){ fac[i] = fac[i-1]*i % mod; }
        inv[N] = finv(fac[N]); for (int i = N; i >= 1; i--){ inv[i-1= inv[i]*i % mod; }
        int n; ll a, b, k; cin >> n >> a >> b >> k;
        ll ans = 0;
        for (int ac = 0; ac <= n; ac++){
            ll as = a*ac; ll bs = k-as;
            if (bs < 0 || bs%b != 0){ continue; }
            ll bc = bs/b;
            if (0 > bc || bc > n){ continue; }
            ans += ncr(n, ac) * ncr(n, bc) % mod; ans %= mod;
        }
        cout << ans;
    }
    cs

    '문제 풀이 > AtCoder' 카테고리의 다른 글

    [ABC271 G] Access Counter  (0) 2023.01.30
    [ABC128 E] Roadwork  (0) 2023.01.30
    [ABC006 D] トランプ挿入ソート  (0) 2023.01.30
    [ABC213 E] Stronger Takahashi  (0) 2023.01.30
    [ABC038 C] 単調増加  (0) 2023.01.30
Designed by Tistory.