Pagini recente » Cod sursa (job #92106) | Cod sursa (job #2056286) | Cod sursa (job #1331298) | Cod sursa (job #1582299) | Cod sursa (job #3347570)
#include<fstream>
#include<vector>
#define mod 3210121
#define ll long long
std::ifstream fin("cowfood.in");
std::ofstream fout("cowfood.out");
const int SMAX=10005;
ll fact[SMAX], inv[SMAX];
int k, s, n;
std::vector<std::vector<int>>experiments;
inline ll lgexp(ll base, ll exp)
{
ll p=1;
while(exp)
{
if(exp&1)
p=(p*base)%mod;
base=(base*base)%mod;
exp>>=1;
}
return p;
}
inline void precalc()
{
fact[0]=fact[1]=1;
for(int i=2; i<SMAX; ++i)
fact[i]=(fact[i-1]*i)%mod;
inv[SMAX-1]=lgexp(fact[SMAX-1], mod-2);
for(int i=SMAX-2; i>=0; --i)
inv[i]=(inv[i+1]*(i+1))%mod;
}
inline ll C(ll N, ll K)
{
if(K==0)
return 1;
ll upper=fact[N];
ll lower=(inv[K]*inv[N-K])%mod;
ll ans=(upper*lower)%mod;
return ans;
}
void read()
{
fin>>k>>s>>n;
for(int i=0; i<n; ++i)
{
std::vector<int>local;
for(int j=0; j<k; ++j)
{
int val;
fin>>val;
local.push_back(val);
}
experiments.push_back(local);
}
}
void combine(std::vector<int>&local, int bit)
{
for(int i=0; i<k; ++i)
local[i]=std::max(local[i], experiments[bit][i]);
}
ll count_greater(std::vector<int>&local)
{
ll cnt=0;
for(int i=0; i<k; ++i)
cnt+=local[i];
ll rem=s-cnt;
ll greater=C(rem+k, k); //putting at most rem units in k boxes
return greater;
}
ll get_failed()
{
ll cnt=0;
for(ll msk=1; msk<(1<<n); ++msk)
{
std::vector<int>local(k, 0);
for(int bit=0; bit<n; ++bit)
{
if(msk&(1<<bit))
combine(local, bit);
}
ll nr=__builtin_popcountll(msk);
ll sign=(nr%2)?1:-1;
ll count=count_greater(local);
cnt=(cnt+sign*count+mod)%mod;
}
return cnt;
}
void solve()
{
ll total=C(s+k, k);
total=(total-s*k-1+mod)%mod; //the one full of zeroes,
ll failed=get_failed();
ll ans=(total-failed+mod)%mod;
fout<<ans;
}
int main()
{
precalc();
read();
solve();
return 0;
}