Cod sursa(job #2638938)

Utilizator loraclorac lorac lorac Data 30 iulie 2020 17:28:28
Problema Cowfood Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.64 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("cowfood.in");
ofstream out("cowfood.out");
typedef long long ll;
const ll mod=3210121;
const ll lim=(1<<20)+3;
ll maxx[2][32][18480],cnt;
ll ord[lim];
ll cb[lim];
ll poz[lim];
ll v[22][32];
ll put[1002];
ll power(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
bool mycmp(ll a,ll b)
{
    return cb[a]<cb[b];
}
int main()
{
    ll k,s,n;
    in>>k>>s>>n;
    for(ll i=0;i<n;++i)
    for(ll j=1;j<=k;++j)
        in>>v[i][j];
    put[0]=1;
    ll fact=1;
    for(ll i=1;i<=k;++i)
        fact=(fact*i)%mod;
    fact=power(fact,mod-2);
    for(ll i=1;i<=s;++i)
    {
        put[i]=fact;
        for(ll j=i+1;j<=i+k;++j)
            put[i]=(put[i]*j)%mod;
    }
    ll supp=(1<<n);
    for(ll i=0;i<supp;++i)
    {
        ord[i]=i;
        cb[i]=__builtin_popcount(i);
    }
    sort(ord,ord+supp,mycmp);
    for(ll i=1;i<=k;++i)
        maxx[0][i][1]=0;
    poz[0]=1;
    ll ans=(put[s]-(s*k+1)%mod+mod)%mod;
    for(ll tt=1;tt<supp;++tt)
    {
        ll t=ord[tt];
        if(cb[ord[tt]]!=cb[ord[tt-1]])
            cnt=0;
        poz[t]=++cnt;
        ll now=cb[t]%2,last=1-now;
        ll cr=t&-t,r=t&-t,b=0;
        while(cr>1) cr>>=1,++b;
        ll apel=poz[t-r],sum=s;
        for(ll i=1;i<=k;++i)
        {
            maxx[now][i][cnt]=max(maxx[last][i][apel],v[b][i]);
            sum-=maxx[now][i][cnt];
        }
        if(now==1) ans=(ans-put[sum]+mod)%mod;
        else ans=(ans+put[sum])%mod;
    }
    out<<ans<<'\n';
    return 0;
}