Cod sursa(job #1344753)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 16 februarie 2015 22:48:16
Problema Pod Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.14 kb
#include<bits/stdc++.h>
using namespace std;

struct cell
{
    int mat[25][25];
};

ifstream fin("pod.in");
ofstream fout("pod.out");

const int MODULO=9901;
const int MMAX=1005;

int n,m,k,ind,a[MMAX],dp[50],dp1[50];
map<int,int>viz;
cell Z,I,C;

inline cell Inmultire(cell A,cell B)
{
    int i,j,l,aux;
    for (i=1;i<=k;i++)
        for (j=1;j<=k;j++)
            {
                aux=0;
                for (l=1;l<=k;l++) aux+=A.mat[i][l]*B.mat[l][j];
                C.mat[i][j]=aux%MODULO;
            }
    return C;
}

inline void Log(cell A,int y)
{
    int cnt=0;
    while (y!=0)
        {
            if (y&1)
                {
                    if (cnt==0) {Z=A;cnt++;}
                    else Z=Inmultire(Z,A);
                    y--;
                }
            A=Inmultire(A,A);
            y>>=1;
        }
}

inline void Init()
{
    int i,j;
    for (i=1;i<=k;i++)
        {
            for (j=1;j<=k;j++) I.mat[j][i]=0;
            I.mat[i+1][i]=1;
        }
    I.mat[k][k]=I.mat[1][k]=1;
}

int main()
{
    int i,j,l,aux;
    fin>>n>>m>>k;
    for (i=1;i<=m;i++)
        {
            fin>>a[i];
            viz[a[i]]=1;
        }
    sort(a+1,a+m+1);
    Init();
    ind=1;
    for (i=1;i<=n && i<=k;i++)
        if (viz.find(i)==viz.end())
            {
                if (i==1 || i==k) dp[i]=1;
                dp[i]+=dp[i-1]+dp[max(0,i-k)];
            }
        else ind++;
    i--;
    while (i<n)
        {
            if (n>=a[ind] && ind<=m)
                {
                    aux=a[ind]-i;
                    i=a[ind];ind++;
                }
            else {aux=n-i;i=n;}
            Log(I,aux);
            //inmultim dp cu Z
            for (j=1;j<=k;j++)
                {
                    aux=0;
                    for (l=1;l<=k;l++) aux=(aux+dp[l]*Z.mat[l][j])%MODULO;
                    dp1[j]=aux;
                }
            for (j=1;j<=k;j++) dp[j]=dp1[j];
            if (i<n) dp[k]=0;
            else if (viz.find(n)!=viz.end()) dp[k]=0;
        }
    if (n<k) fout<<dp[n]<<"\n";
    else fout<<dp[k]<<"\n";
    return 0;
}