Cod sursa(job #467263)

Utilizator DraStiKDragos Oprica DraStiK Data 28 iunie 2010 13:39:35
Problema Pod Scor 15
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 3.02 kb
#include <algorithm>
#include <cstdio>
using namespace std;

#define MOD 9901
#define MAX 1005
#define DIM 50

int mat[DIM][DIM],rez[DIM][DIM];
int bst[5][DIM];
int v[MAX];
int n,m,k;

void read ()
{
    int i;

    scanf ("%d%d%d",&n,&m,&k);
    for (i=1; i<=m; ++i)
        scanf ("%d",&v[i]);
}

void mult (int a[DIM][DIM],int n,int m,int b[DIM][DIM],int p,int q)
{
    int c[DIM][DIM];
    int i,j,k;

    for (i=1; i<=n; ++i)
        for (j=1; j<=q; ++j)
        {
            c[i][j]=0;
            for (k=1; k<=m; ++k)
                c[i][j]=(c[i][j]+(a[i][k]*b[k][j])%MOD)%MOD;
        }
    for (i=1; i<=n; ++i)
        for (j=1; j<=q; ++j)
            a[i][j]=c[i][j];
}

void solve ()
{
    int i,j,p;

    v[++m]=n+1;

    if (v[1]>k)
    {
        for (i=0; i<k; ++i)
            bst[1][i]=1;
        bst[1][k]=2;
        for (i=1; i<=k; ++i)
            rez[i][i]=mat[i+1][i]=1;
        mat[2][k+1]=mat[k+1][k+1]=rez[k+1][k+1]=1;
        for (p=v[1]-k-1; p; p>>=1)
        {
            if (p&1)
                mult (rez,k+1,k+1,mat,k+1,k+1);
            mult (mat,k+1,k+1,mat,k+1,k+1);
        }
        for (i=1; i<=k; ++i)
            mat[1][i]=bst[1][i-1];
        mat[1][k+1]=bst[1][k];
        mult (mat,1,k+1,rez,k+1,k+1);
        for (i=1; i<=k+1; ++i)
            bst[0][i-1]=mat[1][i];
    }
    else
    {
        for (i=0; i<v[1]; ++i)
            bst[0][i]=1;
        if (v[1]!=k)
            bst[0][k]=1;
    }

    for (i=2; i<=m; ++i)
        if (v[i]-v[i-1]>k)
        {
            for (int w=0; w<=k+1; ++w)
                for (int q=0; q<=k+1; ++q)
                    mat[q][w]=rez[q][w]=0;
            bst[1][0]=0;
            for (j=1; j<k; ++j)
                bst[1][j]=bst[0][j+1]+bst[1][j-1];
            bst[1][k]=bst[1][k-1];
            for (j=1; j<=k; ++j)
                rez[j][j]=mat[j+1][j]=1;
            mat[2][k+1]=mat[k+1][k+1]=rez[k+1][k+1]=1;
            for (p=v[i]-v[i-1]-k-1; p; p>>=1)
            {
                if (p&1)
                    mult (rez,k+1,k+1,mat,k+1,k+1);
                mult (mat,k+1,k+1,mat,k+1,k+1);
            }
            for (j=1; j<=k; ++j)
                mat[1][j]=bst[1][j-1];
            mat[1][k+1]=bst[1][k];
            mult (mat,1,k+1,rez,k+1,k+1);
            for (j=1; j<=k+1; ++j)
                bst[0][j-1]=mat[1][j];
        }
        else
        {
            for (j=0; j<=k; ++j)
                bst[1][j]=0;
            for (j=1; j<v[i]-v[i-1]; ++j)
                bst[1][j]=bst[0][j+1]+bst[1][j-1];
            /*for (j=v[i]-v[i-1]-1; j>=0; --j)
                bst[1][j-(v[i]-v[i-1]-1)+k]=bst[1][j];
            for (j=k-1-(v[i]-v[i-1]-1); j>=0; --j)
                bst[1][j]=bst[0][k-((k-1-(v[i]-v[i-1]-1)-j))];*/
            for (j=0; j<=k; ++j)
                bst[0][j]=bst[1][j];
        }
    printf ("%d",bst[0][k]);
}

int main ()
{
    freopen ("pod.in","r",stdin);
    freopen ("pod.out","w",stdout);

    read ();
    solve ();

    return 0;
}