Cod sursa(job #998018)

Utilizator dariusdariusMarian Darius dariusdarius Data 15 septembrie 2013 15:03:52
Problema Cowfood Scor 58
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.36 kb
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int mod=3210121;
int f[20][31];
int p[31];
int pw(int x,int y)
{
	int r;
	for(r=1;y;y>>=1)
	{
		if(y&1) r=(1LL*r*x)%mod;
		x=(1LL*x*x)%mod;
	}
	return r;
}
int invmod(int x) {return pw(x,mod-2);}
int fact[10005];
int C(int n,int k)
{
	int ans=fact[n];
	ans=(1LL*ans*invmod(fact[k]))%mod;
	ans=(1LL*ans*invmod(fact[n-k]))%mod;
	return ans;
}
int d[10005];
int semn[1<<20];
int ind[(1<<20)+1];
int main()
{
	freopen("cowfood.in","r",stdin);
	freopen("cowfood.out","w",stdout);
	int k,s,n;
	scanf("%d%d%d",&k,&s,&n);
	for(int i=0;i<=20;i++) ind[1<<i]=i;
	for(int i=0;i<n;i++)
		for(int j=1;j<=k;j++)
			scanf("%d",&f[i][j]);
	fact[0]=1;
	for(int i=1;i<=s+k-1;i++)
		fact[i]=(1LL*fact[i-1]*i)%mod;
	d[0]=1;
	for(int i=1;i<=s;i++)
		d[i]=(C(i+k-1,k-1)+d[i-1])%mod;
	int ans=0;//C(s+n-1,n-1);fprintf(stderr,"%d\n",ans);
	for(int i=0;i<(1<<n);i++)
	{
		memset(p,0,sizeof(p));
		if(i!=0)
			semn[i]=-semn[i&(i-1)];
		else
			semn[i]=1;
		int S=s;
		for(int I=i;I;I-=(I&(-I)))
		{
			int j=ind[I&(-I)];
			for(int K=1;K<=k;K++)
				if(p[K]<f[j][K])
				{
					S=S+p[K]-f[j][K];
					p[K]=f[j][K];
				}
		}
		//fprintf(stderr,"%d -> %d, %d",i,semn[i],ans);
		ans=ans+semn[i]*d[S];
		while(ans<0)    ans+=mod;
		while(ans>=mod) ans-=mod;
		//fprintf(stderr,"->%d\n",ans);
	}
	printf("%d\n",(ans-s*k-1+mod)%mod);
	return 0;
}