Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <unordered_map>
- using namespace std;
- typedef long long ll;
- ll BIG_PRIME = 1000000007;
- ll norm(ll d, ll MOD) {
- return ((d % MOD) + MOD) % MOD;
- }
- ll Madd (ll x, ll y, ll MOD) {
- return norm (norm(x, MOD) + norm (y, MOD), MOD);
- }
- ll Msub (ll x, ll y, ll MOD) {
- return norm (norm(x, MOD) - norm (y, MOD), MOD);
- }
- ll Mmul (ll x, ll y, ll MOD) {
- return norm (norm(x, MOD) * norm (y, MOD), MOD);
- }
- ll fastpow(ll a, ll n, ll MOD) {
- if (n == 0LL) {
- return 1LL;
- }
- if (n % 2 == 1) {
- return (a * fastpow(a, n - 1, MOD)) % MOD;
- }
- ll tmp = fastpow(a, n / 2, MOD);
- return (tmp * tmp) % MOD;
- }
- ll Mdiv(ll a, ll b, ll PMOD) {
- return Mmul(a, fastpow(b, PMOD - 2LL, PMOD), PMOD);
- }
- unordered_map<ll, unordered_map<ll, unordered_map<ll, unordered_map<ll, ll>>>> dp;
- vector<ll> factorial;
- ll n = 0;
- vector<ll> a;
- ll total_cards;
- vector<ll> first_player_cards_of_type;
- vector<ll> second_player_cards_of_type;
- vector<ll> min_first_share_for_quantity(11, 0);
- vector<ll> count_types_for_quantity(11, 0);
- ll permutations_first() {
- ll numerator = factorial[total_cards / 2];
- ll denominator = 1;
- for (ll i = 1; i <= n; ++i) {
- denominator = Mmul(denominator, factorial[first_player_cards_of_type[i]], BIG_PRIME);
- }
- return Mdiv(numerator, denominator, BIG_PRIME);
- }
- ll permutations_second() {
- ll numerator = factorial[total_cards / 2];
- ll denominator = 1;
- for (ll i = 1; i <= n; ++i) {
- denominator = Mmul(denominator, factorial[second_player_cards_of_type[i]], BIG_PRIME);
- }
- return Mdiv(numerator, denominator, BIG_PRIME);
- }
- ll total_permutations() {
- ll numerator = factorial[total_cards];
- ll denominator = 1;
- for (ll i = 1; i <= n; ++i) {
- denominator = Mmul(denominator, factorial[a[i]], BIG_PRIME);
- }
- return Mdiv(numerator, denominator, BIG_PRIME);
- }
- ll f(ll idx, ll delta, ll real_delta, ll first_player_total_cards, ll second_player_total_cards) {
- if (idx > n) {
- if (first_player_total_cards == second_player_total_cards &&
- second_player_total_cards == total_cards / 2)
- {
- /*
- // Check delta is OK
- ll real_delta = 0;
- for (ll i = 1; i <= n; ++i) {
- if (first_player_cards_of_type[i] == a[i]) {
- ++real_delta;
- } else if (second_player_cards_of_type[i] == a[i]) {
- --real_delta;
- }
- }
- */
- if (delta == real_delta) {
- vector<vector<ll>> count_for_quantity_and_first_share(11, vector<ll> (11, 0));
- for (int i = 1; i <= n; ++i) {
- ++count_for_quantity_and_first_share[a[i]][first_player_cards_of_type[i]];
- }
- /*
- for (ll i = 1; i <= n; ++i) {
- cout << first_player_cards_of_type[i] << " ";
- }
- cout << endl;
- */
- ll numerator = 1;
- ll denominator = 1;
- for (ll quantity = 1; quantity <= 10; ++quantity) {
- numerator = Mmul(
- numerator,
- factorial[count_types_for_quantity[quantity]],
- BIG_PRIME
- );
- for (ll first_share = 0; first_share <= quantity; ++first_share) {
- denominator = Mmul(
- denominator,
- factorial[count_for_quantity_and_first_share[quantity][first_share]],
- BIG_PRIME
- );
- }
- }
- ll number_of_type_permutations = Mdiv(numerator, denominator, BIG_PRIME);
- ll number_of_permutations = Mmul(permutations_first(), permutations_second(), BIG_PRIME);
- ll res = Mmul(number_of_permutations, number_of_type_permutations, BIG_PRIME);
- //cout << res << endl;
- return res;
- }
- }
- return 0;
- }
- if (first_player_total_cards > total_cards / 2 || second_player_total_cards > total_cards / 2) {
- return 0;
- }
- if (abs(delta - real_delta) > 2 * (n + 1 - idx)) {
- return 0;
- }
- /*
- first_player_cards_of_type[idx] = a[idx];
- second_player_cards_of_type[idx] = 0;
- ll first_win = f(
- idx + 1,
- delta - 1,
- real_delta + 1,
- first_player_total_cards + a[idx],
- second_player_total_cards + 0
- );
- first_player_cards_of_type[idx] = 0;
- second_player_cards_of_type[idx] = a[idx];
- ll first_lose = f(
- idx + 1,
- delta + 1,
- real_delta - 1,
- first_player_total_cards + 0,
- second_player_total_cards + a[idx]
- );
- */
- ll res = 0;
- for (ll i = min_first_share_for_quantity[a[idx]]; i <= a[idx]; ++i) {
- ll tmp = min_first_share_for_quantity[a[idx]];
- min_first_share_for_quantity[a[idx]] = i;
- first_player_cards_of_type[idx] = i;
- second_player_cards_of_type[idx] = a[idx] - i;
- ll diff_delta = 0;
- ll diff_real_delta = 0;
- if (i == 0) {
- diff_delta = 1;
- diff_real_delta = -1;
- } else if (i == a[idx]) {
- diff_delta = -1;
- diff_real_delta = 1;
- }
- res = Madd(
- res,
- f(
- idx + 1,
- delta + diff_delta,
- real_delta + diff_real_delta,
- first_player_total_cards + i,
- second_player_total_cards + (a[idx] - i)
- ),
- BIG_PRIME
- );
- min_first_share_for_quantity[a[idx]] = tmp;
- }
- return res;
- }
- int main() {
- cin >> n;
- a.resize(n + 1);
- first_player_cards_of_type.resize(n + 1);
- second_player_cards_of_type.resize(n + 1);
- for (ll i = 1; i <= n; ++i) {
- cin >> a[i];
- total_cards += a[i];
- ++count_types_for_quantity[a[i]];
- }
- factorial.resize(501);
- factorial[0] = 1;
- for (ll i = 1; i <= total_cards; ++i) {
- factorial[i] = Mmul(factorial[i - 1], i, BIG_PRIME);
- }
- ll numerator = f(1, 0, 0, 0, 0);
- ll denominator = total_permutations();
- cout << "Total card: " << total_cards << endl
- << "Good permutations: " << numerator << endl
- << "Total permutations: " << denominator << endl
- << "Prob: " << Mdiv(numerator, denominator, BIG_PRIME) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement