Cod sursa(job #467619)

Utilizator S7012MYPetru Trimbitas S7012MY Data 29 iunie 2010 17:54:33
Problema Pod Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define DIM 25
#define DM 1005
#define REST 9901
typedef long long mat22[DIM][DIM];
int capa,lipsa[DM],din[DIM];
mat22 m1,m2,sol;

void inmultire(mat22 a,mat22 b) {
	int i,j,k,ceva;
	mat22 c;
	for(i=1; i<=capa; i++)
		for(j=1; j<=capa;j++) {
			ceva=0;
			for(k=1; k<=capa; k++)
				ceva+=a[i][k]*b[k][j];
            c[i][j]=ceva%REST;
		}
    memcpy(a,c,sizeof c);
}

void putere(int k, mat22 sol) {
	mat22 aux;
	memcpy(aux,m1, sizeof m1);
	for(; k; k >>= 1) {
		if(k & 1)
			inmultire(sol, aux);
		inmultire(aux, aux);
	}
}

void matun() {
	for(int i=1; i<=capa; i++)
		sol[i][i]=1;
}

int main()
{
	int n,m,i;
	freopen("pod.in","r",stdin);
	freopen("pod.out","w",stdout);
	scanf("%d %d %d", &n,&m,&capa);
	for(i=1; i<=m; i++) scanf("%d",&lipsa[i]);
	lipsa[++m]=n+1;
	sort(lipsa+1,lipsa+m+1);
	///<construire matrici>
	matun();
	m1[1][1]=m1[capa][1] = 1;
	for(i=2; i<=capa; i++) m1[i-1][i]=m2[i-1][i]=1;
	///</construire>
	for(i=1; i<=m; i++) {
	    if(lipsa[i]<=capa) continue;
	    putere(lipsa[i]-max(capa, lipsa[i-1])-1,sol);
	    if(lipsa[i]<=n)
	        inmultire(sol,m2);
	}

	int vect[DIM];
	vect[0] = 1;
	for(i = 1; i <=capa; ++i) {
		vect[i] = 0;
        bool ok = 0;
		for(int j = 1; j <= m; ++j)
			if(i == lipsa[j])
				ok = true;
		if(ok) continue;
		vect[i] += vect[i-1];
		if(vect[i] > REST)
			vect[i] -= REST;
		if(i==capa) {
			vect[i] += vect[i-capa];
			if(vect[i]>REST)
				vect[i] -= REST;
		}
	}

	for(i = 1; i <= capa; ++i) din[i] = vect[capa+1-i];
	int Sol=0;
	for(i = 1; i <= capa; ++i) {//inmultire vector
		Sol += din[i] * sol[i][1];
		Sol %= REST;
	}
	printf("%d",Sol);
	return 0;
}