Cod sursa(job #467038)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 28 iunie 2010 11:06:04
Problema Pod Scor 95
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 2.16 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

#define maxn 1010
#define maxk 21
#define mod 9901

int n, m, k, ind, poz;
int p[maxn], mat[maxk][maxk], o[maxk][maxk], aux[maxk][maxk];
int d[maxn*maxk], dn[maxn*maxk];

void inm(int nr)
{
    if(nr==1)
    {
        for(char i=1; i<=k; ++i)
            for(char j=1; j<=k; ++j)
                mat[i][j]=o[i][j];
        return;
    }
    inm(nr/2);
    memset(aux, 0, sizeof(aux));
    for(char i=1; i<=k; ++i)
        for(char j=1; j<=k; ++j)
            for(char l=1; l<=k; ++l)
                aux[i][j]=(aux[i][j]+mat[i][l]*mat[l][j])%mod;
    for(char i=1; i<=k; ++i)
        for(char j=1; j<=k; ++j)
            mat[i][j]=aux[i][j];
    if(nr%2)
    {
        memset(aux, 0, sizeof(aux));
        for(char i=1; i<=k; ++i)
            for(char j=1; j<=k; ++j)
                for(char l=1; l<=k; ++l)
                    aux[i][j]=(aux[i][j]+mat[i][l]*o[l][j])%mod;
        for(char i=1; i<=k; ++i)
            for(char j=1; j<=k; ++j)
                mat[i][j]=aux[i][j];
    }
}



int main()
{
    freopen("pod.in", "r", stdin);
    freopen("pod.out", "w", stdout);
    scanf("%d%d%d", &n, &m, &k);
    d[0]=1;
    for(int i=1; i<=m; i++)
        scanf("%d", &p[i]);
    p[++m]=n;
    p[++m]=0;
    sort(p+1, p+m+1);
    poz=0;
    ind=0;
    d[k]=1;
    for(int i=1; i<k; i++)
        o[i+1][i]=1;
    o[k][k]=o[1][k]=1;
    for(int i=2; i<=m; ++i)
    {
        if(p[i]-p[i-1]>k)
        {
            inm(p[i]-p[i-1]);
            for(char j=1; j<=k; ++j)
            {
                dn[j]=0;
                for(char l=1; l<=k; ++l)
                    dn[j]=(dn[j]+d[l]*mat[l][j])%mod;
            }
            ind=p[i];
            for(char j=1; j<=k; ++j)
                d[j]=dn[j];
            if(p[i]<n)
                d[k]=0;
        }
        else
        {
            for(int j=k+1; j<=k+p[i]-ind; j++)
                if(j!=k+p[i]-ind || p[i]==n)
                    d[j]=(d[j-k]+d[j-1])%mod;
                else
                    d[j]=0;
            for(int j=1; j<=k; ++j)
                d[j]=d[j+p[i]-ind];
            ind=p[i];
        }
    }
    printf("%d\n", d[k]);
    return 0;
}