Cod sursa(job #2534211)

Utilizator ptudortudor P ptudor Data 30 ianuarie 2020 11:15:33
Problema Cowfood Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <bits/stdc++.h>
#define P 3210121
#define ll long long
using namespace std;

ifstream in("cowfood.in");
ofstream out("cowfood.out");

ll k,s,n,expe[21][31];
vector<ll> mashup(vector<ll> &st , ll f)
{ll i,j;
   //cout << "facem mashup la st = ";
   //for (i = 0; i < f; i++) cout << st[i] << " "; cout << "\n";

   vector<ll> rez;
   rez.resize(k + 1 , 0);
   for (j = 1; j <= k; j++)
   {
      for (i = 0; i < f; i++)
         rez[j] = max(rez[j] , expe[st[i]][j]);
   }
   //for (int r = 1; r <= k; r++) cout << rez[r] << " "; cout << "\n";
   return rez;
}
ll sol = 0,fact[50];
ll la_put(ll x , ll y)
{
   ll put = x , s = 1,y2 = y;
   while (y)
   {
      //cout << " y=" << y  << " put=" << put << " s=" << s << "\n";
      if (y % 2)
         s = (s * put) % P;
      y /= 2;
      put = (put * put) % P;
   }
   //cout << " y=" << y  << " put=" << put << " s=" << s << "\n";
   //cout << x << "^" << y2 << " = " << s << "\n";
   return s;
}
ll inv_mod(ll x)
{
   return la_put(x , P - 2);
}
void combinatii(vector<ll> &st,ll f, ll n, ll i)
{
   if (i >= f)
   {
      vector<ll> nr;
      nr.resize(k + 1 , 0);
      for (int cif = 1; cif <= k; cif++)
         for (int j = 0; j < f; j++)
            nr[cif] = max(nr[cif] , expe[st[j]][cif]);
      int s2 = s;
      for (i = 1; i <= k; i++)
         s2 -= nr[i];
      /*cout << "st : ";
      for (int i = 0; i < f; i++)
         cout << st[i] << " ";
         cout << "\n";
      cout << "nr : ";
      for (int i = 1; i <= k; i++)
         cout << nr[i] << " ";
         cout << "\n";*/
      if (s2 > 0)
      {
         int x2 = fact[s2 + k - 1] * inv_mod(fact[k - 1] * fact[s2 - 1] % P);
         if (f % 2 == 1)
            sol = (sol + x2) % P;
         else
            sol = (sol - x2) % P;
      }
   }
   else
   {
      ll lmt = (i > 0) ? st[i - 1] + 1 : 1;
      for (ll j = lmt; j <= n - (f - i) + 1; j++)
      {
         st[i] = j;
         combinatii(st , f , n , i + 1);
      }
   }
}
/// n inseamna pana unde pot sa mearga numerele
/// f inseamna cat de multe numere sunt
int main()
{ll i,j,f;
   in >> k >> s >> n;
   for (i = 1; i <= n; i++)
      for (j = 1; j <= k ; j++)
         in >> expe[i][j];
   fact[1] = fact[0] = 1;
   for (i = 2; i <= 50; i++)
      fact[i] = 1LL * fact[i - 1] * i % P;
   vector<ll> v;
   for (f = 1; f <= n; f++)
   {
      v.clear();
      v.resize(f);
      combinatii(v , f , n , 0);
   }
   if (sol < 0) sol += P;
   out << sol % P << "\n";
}

///vrem sa stim cum se calculeaza combinatiile
///vrem sa mergem prin toate submultimile de 2 si sa le scaden
///toate alea de 3 si sa le adunam si etc si asa aflam numarul