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;
- 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 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) {
- return Mmul(permutations_first(), permutations_second(), BIG_PRIME);
- }
- }
- return 0;
- }
- if (first_player_total_cards > total_cards / 2 || second_player_total_cards > total_cards / 2) {
- return 0;
- }
- /*
- if (dp[n][delta][first_player_total_cards].count(second_player_total_cards) != 0) {
- return dp[n][delta][first_player_total_cards][second_player_total_cards];
- }
- */
- first_player_cards_of_type[idx] = a[idx];
- second_player_cards_of_type[idx] = 0;
- ll first_win = f(
- idx + 1,
- 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,
- first_player_total_cards + 0,
- second_player_total_cards + a[idx]
- );
- ll draw = 0;
- for (ll i = 1; i < a[idx]; ++i) {
- first_player_cards_of_type[idx] = i;
- second_player_cards_of_type[idx] = a[idx] - i;
- draw = Madd(
- draw,
- f(
- idx + 1,
- delta,
- first_player_total_cards + i,
- second_player_total_cards + (a[idx] - i)
- ),
- BIG_PRIME
- );
- }
- //dp[n][delta][first_player_total_cards][second_player_total_cards] = Madd(draw, Madd(first_win, first_lose, BIG_PRIME), BIG_PRIME);
- //return dp[n][delta][first_player_total_cards][second_player_total_cards];
- return Madd(draw, Madd(first_win, first_lose, BIG_PRIME), BIG_PRIME);
- }
- 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];
- }
- 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);
- ll denominator = total_permutations();
- cout << "total card: " << total_cards << endl;
- cout << numerator << endl << denominator << endl;
- cout << Mdiv(numerator, denominator, BIG_PRIME) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement