Challenge: Alien Flowers
Subdomeniu: Combinatorics (combinatorics)
Scor cont: 60.0 / 60
Submission status: Accepted
Submission score: 1.0
Submission ID: 464755270
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/alien-flowers/problem
Cerinta
Meera bought a house on Mars, and plans to decorate it with chains of alien flowers. Each flower is either red ($R$) or blue ($B$), and Meera knows how many occurrences of `RR`, `RB`, `BB`, and `BR` she wants to see in a chain.
The diagram below shows a flower chain of length $10$:
<img src="https://s3.amazonaws.com/hr-challenge-images/14591/1453204624-d20e72c6a1-ornament.jpg" title="ornament.jpg" />
In this example, `RR` occurs $2$ times (at positions $0$ and $4$), `RB` occurs $3$ times (at positions $1$, $5$, and $7$), `BB` occurs $1$ time (at position $2$), and `BR` occurs $3$ times (at positions $3$, $6$, and $8$).
Meera wants your help determining how many different chains with *positive length* can be made. Given $A, B, C$, and $D$, find the number of different chains having occurrences of `RR`, `RB`, `BB` and `BR` equal to inputs $A, B, C$, and $D$, respectively. As the answer can be very large, your printed output should be $answer \ \% \ (10^9+7)$.
Input Format
One line of space-separated, non-negative integers: $A$ (occurrences of `RR`), $B$ (occurrences of `RB`), $C$ (occurrences of `BB`), and $D$ (occurrences of `BR`), respectively.
Output Format
Find the number of chains having $A, B, C$, and $D$ occurrences of `RR`, `RB`, `BB`, and `BR`, respectively, and print the $answer \ \% \ (10^9+7)$.
Constraints
* For $20\%$ Points: $0 \leq A,B,C,D \leq 4$
* For $50\%$ Points: $0 \leq A,B,C,D \leq 10^2$
* For $100\%$ Points: $0 \leq A,B,C,D \leq 10^5$
Cod sursa
#include <bits/stdc++.h>
using namespace std;
static const long long MOD = 1000000007LL;
long long mod_pow(long long a, long long e) {
long long r = 1 % MOD;
a %= MOD;
while (e > 0) {
if (e & 1) r = (r * a) % MOD;
a = (a * a) % MOD;
e >>= 1;
}
return r;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long rr, rb, bb, br;
cin >> rr >> rb >> bb >> br;
if (llabs(rb - br) > 1) {
cout << 0 << '\n';
return 0;
}
long long maxK = max(rb, br);
if (maxK >= MOD) {
// Not expected under problem constraints.
cout << 0 << '\n';
return 0;
}
vector<long long> inv((size_t)maxK + 1, 1);
for (long long i = 2; i <= maxK; ++i) {
inv[(size_t)i] = MOD - (MOD / i) * inv[(size_t)(MOD % i)] % MOD;
}
auto comb = [&](long long n, long long k) -> long long {
if (k < 0 || k > n) return 0;
k = min(k, n - k);
long long res = 1;
for (long long i = 1; i <= k; ++i) {
long long num = (n - k + i) % MOD;
res = (res * num) % MOD;
res = (res * inv[(size_t)i]) % MOD;
}
return res;
};
auto ways = [&](long long internal, long long runs) -> long long {
if (runs == 0) return internal == 0 ? 1LL : 0LL;
return comb(internal + runs - 1, runs - 1);
};
long long ans = 0;
if (rb == br) {
long long t = rb;
// Start and end with R: R-runs=t+1, B-runs=t
ans = (ans + ways(rr, t + 1) * ways(bb, t)) % MOD;
// Start and end with B: R-runs=t, B-runs=t+1
ans = (ans + ways(rr, t) * ways(bb, t + 1)) % MOD;
} else if (rb == br + 1) {
long long t = rb;
// Start with R, end with B: R-runs=t, B-runs=t
ans = (ans + ways(rr, t) * ways(bb, t)) % MOD;
} else {
long long t = br;
// Start with B, end with R: R-runs=t, B-runs=t
ans = (ans + ways(rr, t) * ways(bb, t)) % MOD;
}
cout << ans % MOD << '\n';
return 0;
}
HackerRank Combinatorics – Alien Flowers
