Cod sursa(job #1482184)

Utilizator andrettiAndretti Naiden andretti Data 6 septembrie 2015 17:49:08
Problema Pod Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include<stdio.h>
#include<algorithm>
#define maxn 25
#define maxm 1005
#define MOD 9901
using namespace std;

int n,m,K;
int a[maxn][maxn],add[maxn][maxn],b[maxn][maxn];
int sol[maxn][maxn],dp[maxn];
int gap[maxm];

void read()
{
    scanf("%d %d %d",&n,&m,&K);
    for(int i=1;i<=m;i++) scanf("%d",&gap[i]);
}

void mult(int a[maxn][maxn],int b[maxn][maxn])
{
    int aux[maxn][maxn];

    for(int i=1;i<=K;i++)
     for(int j=1;j<=K;j++)
     {
         aux[i][j]=0;
         for(int k=1;k<=K;k++){
             aux[i][j]+=(a[i][k]*b[k][j])%MOD;
             if(aux[i][j]>=MOD) aux[i][j]-=MOD;
         }
     }

     for(int i=1;i<=K;i++)
      for(int j=1;j<=K;j++)
       a[i][j]=aux[i][j];
}

void mat_pow(int p)
{
    for(int i=1;i<K;i++)
    {
        for(int j=1;j<=K;j++)
         add[j][i]=0;

        add[i+1][i]=1;
    }

    for(int i=1;i<=K;i++) add[i][K]=0;
    add[1][K]=add[K][K]=1;

    for(int i=1;i<=K;i++)
     for(int j=1;j<=K;j++)
      if(i==j) a[i][j]=1;
      else a[i][j]=0;

    for(int i=0;p>>i;i++)
    {
        if(((p>>i)&1)) mult(a,add);
        mult(add,add);
    }
}

void solve()
{
    sort(gap+1,gap+m+1);

    if(K>n)
    {
        if(m) printf("0");
        else printf("1");
        return;
    }

    for(int i=1;i<=K;i++)
     for(int j=1;j<=K;j++)
      if(i==j) sol[i][j]=1;

    for(int i=1;i<K;i++) b[i+1][i]=1;

    int L,cnt;
    for(L=1;L<=m && gap[L]<K;L++);

    int p;
    for(cnt=K;cnt<=n;)
    {
        if(L>m)
        {
            p=n-cnt+1;
            mat_pow(p);
            mult(sol,a);
            break;
        }

        p=gap[L]-cnt;
        if(p>0){
            mat_pow(p);
            mult(sol,a);
        }
        mult(sol,b); cnt=gap[L]+1; L++;
    }

    L=1;
    dp[0]=1;
    for(int i=1;i<K;i++)
     if(L<=m && i==gap[L])
      dp[i]=0,L++;
     else dp[i]=dp[i-1];

    int res=0;
    for(int i=1;i<=K;i++)
    {
        res+=(dp[i-1]*sol[i][K])%MOD;
        if(res>=MOD) res-=MOD;
    }

    printf("%d",res);
}

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

    read();
    solve();

    fclose(stdin);
    fclose(stdout);
    return 0;
}