Cod sursa(job #717499)

Utilizator mihai995mihai995 mihai995 Data 19 martie 2012 22:39:52
Problema Cowfood Scor 58
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <fstream>
using namespace std;

const int N=21,K=31,S=15001,mod=3210121;
int fact[S],invfact[S],s,k,n,rez;

ifstream in("cowfood.in");
ofstream out("cowfood.out");

inline int calc(int a,int b)
{
    return (int)((long long)a*b%mod);
}

inline int comb(int n,int k)
{
    return calc(fact[n],calc(invfact[k],invfact[n-k]));
}

struct Try
{
    int a[K];
    int val()
    {
        int sum=0;
        for (int i=1;i<=k;i++)
            sum+=a[i];
        return comb(s-sum+k,k);
    }
    void merge(Try x)
    {
        for (int i=1;i<=k;i++)
            a[i]=max(a[i],x.a[i]);
    }
    void init()
    {
        for (int i=0;i<=k;i++)
            a[i]=0;
    }
    void get()
    {
        for (int i=1;i<=k;i++)
            in>>a[i];
    }
} a[N],zero;

void euclid(int a,int b,int &x,int &y)
{
    if (!b)
    {
        x=1;
        y=0;
        return;
    }
    int x1,y1;
    euclid(b,a%b,x1,y1);
    x=y1;
    y=x1-a/b*y1;
}

int inv(int x)
{
    int a,b;
    euclid(x,mod,a,b);
    a=(a%mod+mod)%mod;
    return a;
}

void calc_comb(int n)
{
    fact[0]=invfact[0]=1;
    for (int i=1;i<=n;i++)
        fact[i]=calc(i,fact[i-1]);
    invfact[n]=inv(fact[n]);
    for (int i=n-1;i;i--)
        invfact[i]=calc(invfact[i+1],i+1);
}

void pie(int p,int semn,Try lim)
{
    if (p==n+1)
    {
        rez=(rez+semn*lim.val())%mod;
        return;
    }
    pie(p+1,semn,lim);
    lim.merge(a[p]);
    pie(p+1,-semn,lim);
}

int main()
{
    calc_comb(S-1);
    in>>k>>s>>n;
    for (int i=1;i<=n;i++)
        a[i].get();
    rez-=s*k+1;
    pie(1,1,zero);
    out<<rez<<"\n";
    return 0;
}