Cod sursa(job #467026)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 28 iunie 2010 11:01:54
Problema Pod Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 2.65 kb
#include<cstdio>
#include<algorithm>
using namespace std;
const int X=9901;
int rez,n,m,x,y,z,k,pi,kk,p,s[1004][25],fac[X+1],g[1004];
void eucl(int a,int b,int &x,int &y,int &d)
{
    if(b==0)
    {
		x=1;
		y=0;
		d=a;
		return;
	}
	int x1,y1;
	eucl(b,a%b,x1,y1,d);
	x=y1;
	y=x1-(a/b)*y1;
}
int getfact(int n,int pr)
{
	int rez=0;
	while(n>=pr)
	{
		rez+=n/pr;
		n/=pr;
	}
	return rez;
}
int inversmod(int a)
{
	int x,y,d;
	x=y=d=0;
	eucl(a,X,x,y,d);
	if(x>0)
		return x%X;
	return X+x%X;
}
int comb(int a,int b)
{
	int put=1,rez=1;
	while(put<=a/X)
		put*=X;
	for(;put;put/=X)
	{
		int m=a/put,n=b/put;
		a-=m*put;
		b-=n*put;
		rez=rez*(((fac[m]*inversmod(fac[n]))%X)*inversmod(fac[m-n]))%X;
	}
	return rez;
}
int rezolv(int a,int b)
{
	int prod=0;
	prod=comb(a,b);
	return prod;
}
void pregen(int pr)
{
	fac[0]=1;
	for(int i=1;i<pr;i++)
		fac[i]=(fac[i-1]*i)%pr;
}
int each(int n,int m)
{
    x=getfact(n,X);
    y=getfact(m,X);
    z=getfact(n-m,X);
    if(x==y+z)
        return rezolv(n,m);
    else return 0;
}
int sum(int n,int m)
{
    int st=0;
    for(int i=m;i<=n;i+=k)
        st=(st+each(n,i))%X;
    return st;
}
int main()
{
    freopen("pod.in","r",stdin);
    freopen("pod.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    pregen(X);
    for(int i=1;i<=m;i++)
        scanf("%d",&g[i]);
    sort(g+1,g+m+1);
    pi=0;
    if(k!=1)
    {
        if(m!=0)
        {
            for(int j=g[1]-k+1;j<=g[1]-1;j++)
            {
                kk=(j-pi)/k;
                p=j-k*kk;
                s[1][j+k-g[1]]+=sum(j-pi,p);
                s[1][j+k-g[1]]%=X;
            }
            for(int i=2;i<=m;i++)
            {
                for(int j=g[i]-k+1;j<=g[i]-1;j++)
                {
                    for(int l=1;l<k;l++)
                    {
                        pi=g[i-1]+l;
                        kk=(j-pi)/k;
                        p=j-pi-k*kk;
                        s[i][j+k-g[i]]+=s[i-1][l]*sum(j-pi,p);
                        s[i][j+k-g[i]]%=X;
                    }
                }
            }
            for(int l=1;l<k;l++)
            {
                pi=g[m]+l;
                kk=(n-pi)/k;
                p=n-pi-k*kk;
                rez=(rez+s[m][l]*sum(n-pi,p))%X;
            }
            printf("%d\n",rez);
        }
        else
        {
            pi=0;
            kk=(n-pi)/k;
            p=n-pi-k*kk;
            rez=(rez+sum(n-pi,p))%X;
            printf("%d\n",rez);
        }
    }
    else if(k==1)
    {
        if(m==0)
            printf("1\n");
        else printf("0");
    }
    return 0;
}