Cod sursa(job #2534188)

Utilizator ptudortudor P ptudor Data 30 ianuarie 2020 10:29:34
Problema Cowfood Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.74 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);
}
ll combinations(vector<ll> rez, ll f)
{
   ll s2 = s,i;
   for (i = 1; i <= k; i++) cout << rez[i] << " "; cout << "\n";
   for (i = 1; i <= k; i++)
      s2 -= rez[i];
   if (s2 <= 0)
      return 0;
   ll K = k - 1 , N = s2 + K;
   ll cc = ( fact[N] * inv_mod( fact[K] * fact[N - K] % P) ) % P;
   cout << cc << " sol = " << sol << "\n\n";
   return cc;
}
/**

3 bare -> k = 4
9 zerouri adica S2 = 9
S2 = s - suma elementelor la momentul actual
rezultatul egal cu combinari (k - 1) + S2 luate cate (k - 1)
000|00|00|00
*/
void out_comp(vector<ll> &st , ll f)
{
   ll i, p = ( ( f % 2 ) == 0 ) ? -1 : 1;

   for (i = 0; i < f; i++)cout << st[i] << " ";cout << "\n";

   sol = ( sol + p * combinations(mashup(st , f) , f) ) % P;
}
void combinatii(vector<ll> &st,ll f, ll n, ll i)
{
   if (i >= f)
      out_comp(st , f);
   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