Cod sursa(job #2009673)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 10 august 2017 14:03:40
Problema Cowfood Scor 2
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include<bits/stdc++.h>
#define maxN 35
#define MOD 3210121
using namespace std;
long long st[maxN],n,a[maxN][maxN];
long long pr;
long long dp[30005][35];
inline long long FastExp(long long a,long long b)
{
    long long rez=1LL;
    while(b)
    {
        if(b&1)
        {
            rez=(rez*a)%MOD;
            b--;
        }
            else
        {
            a=(a*a)%MOD;
            b>>=1;
        }
    }
    return rez;
}
long long k,s,sol[maxN],so,ans;
inline void Solve(int p)
{
    long long nr=0;
    for(int i=1;i<=n;i++)
        nr+=st[i];
    if(!nr) return; //eliminam multimea vida
    for(int j=1;j<=k;j++)
    {
        sol[j]=0;
    }
    for(int i=1;i<=n;i++)
    {
        if(!st[i]) continue;
        for(int j=1;j<=k;j++)
        {
            sol[j]=max(sol[j],a[i][j]);
        }
    }
    long long sum=0;
    for(int j=1;j<=k;j++)
        sum=sum+sol[j];
    if(sum>s) return;
    so=FastExp(k,s-sum+1)-1;
    while(so<-MOD) so+=MOD;
    so=so*FastExp(k-1,MOD-2);
    if(nr%2)
    {
        ans=(ans+so)%MOD;

    }
        else
    {
        ans=(ans-so+MOD)%MOD;
    }
}
inline long long C(long long n,long long k)
{
    long long comb;
    long long nf=1LL,kf=1LL,xf=1LL;
    for(long long i=1;i<=n;i++)
    {
        nf=(nf*i)%MOD;
    }
    for(long long i=1;i<=k;i++)
    {
        kf=(kf*i)%MOD;
    }
    for(long long i=1;i<=n-k;i++)
    {
        xf=(xf*i)%MOD;
    }
    comb=nf;
    comb=(comb*FastExp(kf,MOD-2))%MOD;
    comb=(comb*FastExp(xf,MOD-2))%MOD;
    return comb;
}
inline void Pinex(int p)
{
    for(int i=0;i<=1;i++)
    {
        st[p]=i;
        if(p==n) Solve(p);
            else Pinex(p+1);
    }
}
int main()
{
    freopen("cowfood.in","r",stdin);
    freopen("cowfood.out","w",stdout);
    scanf("%lld%lld%lld",&k,&s,&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            scanf("%lld",&a[i][j]);
        }
    }
    /**
        Vedem cate experimente vor esua
    **/

    dp[1][1]=n;
    /**
        dp[i][j]-in cate feluri poti obtine suma i din j gramezi
    **/
    for(int i=2;i<=s;i++)
    {
    pr=(pr+C(i+n-1LL,n-1LL)-n)%MOD;
    while(pr<-MOD) pr+=MOD;
    }
    Pinex(1);
    pr-=ans;
    while(pr<-MOD) pr+=MOD;
    printf("%lld\n",pr);
    return 0;
}