Cod sursa(job #1263226)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 14 noiembrie 2014 10:08:54
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <fstream>
#include <algorithm>
#include <cstring>

#define mod 3210121
using namespace std;

int comb[10055][55];

inline void precalc_comb(){

    int j;
    for(int i=0;i<10055;i++){
        comb[i][0]=1;

        for(j=1;j<=i && j<55;j++){
            comb[i][j]=(comb[i-1][j-1]+comb[i-1][j]);
            if(comb[i][j]>=mod)
                comb[i][j]-=mod;
        }
    }
}

inline int combinari(int n,int s){
    if(s<0)
        return 0;

    return comb[n+s][n];
}

short logar[1048605];

inline void precalc_logar(){
    for(int i=1,j=0;i<1048605;i<<=1,j++)
        logar[i]=j;
}

#define lsb(x) ((x)&(-x))

int exps[25][35];
int maxim[1048605];
int suma[1048605];

int sum[25];
int posibil[35];

int main()
{
    ifstream cin("cowfood.in");
    ofstream cout("cowfood.out");

    precalc_comb();
    precalc_logar();

    int n=0,s=2,k=2;
    cin>>k>>s>>n;

    int i,j;
    for(i=1;i<=k;i++)
        posibil[i]=s;

    for(i=0;i<n;i++){
        for(j=1;j<=k;j++){
            cin>>exps[i][j];
            sum[i]+=exps[i][j];
        }

        if(!sum[i]){
            cout<<"0\n";

            cin.close();
            cout.close();
            return 0;
        }
    }

    for(i=1;i<=k;i++){
        for(j=0;j<n;j++)
            if(sum[j]==exps[j][i])
                posibil[i]=sum[j];
    }

    int sum_inutil=0;
    for(i=1;i<=k;i++)
        sum_inutil+=posibil[i];

    sum_inutil++;
    sum_inutil%=mod;

    for(j=1;j<=k;j++){
        memset(maxim,0,sizeof(maxim));

        for(i=1;i<(1<<n);i++){
            maxim[i]=max(maxim[i-lsb(i)],exps[logar[lsb(i)]][j]);
            suma[i]+=maxim[i];
        }
    }

    int ans=(combinari(k,s)+mod-sum_inutil)%mod;
    for(i=1;i<(1<<n);i++)
        if(__builtin_popcount(i)&1){
            ans-=combinari(k,s-suma[i]);

            if(ans<0)
                ans+=mod;
        }
        else{
            ans+=combinari(k,s-suma[i]);
            if(ans>=mod)
                ans-=mod;
        }

    cout<<ans<<'\n';

    cin.close();
    cout.close();
    return 0;
}