Cod sursa(job #2243341)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 20 septembrie 2018 12:31:25
Problema Pod Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <stdio.h>
#include <algorithm>
using namespace std;

int n, m, k, poz[1005], mod=9901;
int dp[40], F[40][2], T[40][40];
void inm(int a[40][40], int b[40][40]){

    int rez[40][40];
    int i,j,l;
    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            {
                rez[i][j]=0;
                for(l=1; l<=k; l++)
                {
                    rez[i][j]+=(a[i][l]*b[l][j])%mod;
                    rez[i][j]%=mod;
                }
            }
    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            a[i][j]=rez[i][j];
}
void ridica(int T[40][40], int p){

    int rez[40][40];
    for(int i=1; i<=k; i++)
        for(int j=1; j<=k; j++)
            if(i==j) rez[i][j]=1;
            else rez[i][j]=0;
    while(p>0){
        if(p&1) inm(rez, T);
        inm(T,T);
        p=p>>1;
    }
    for(int i=1; i<=k; i++)
        for(int j=1; j<=k; j++)
            T[i][j]=rez[i][j];
}
void inmulteste(int T[40][40], int F[40][2]){

    int rez[40][2];
    int i, j;
    for(i=1; i<=k; i++){
        rez[i][1]=0;
        for(j=1; j<=k; j++){
            rez[i][1]+=(T[i][j]*F[j][1])%mod;
            rez[i][1]%=mod;
        }
    }
    for(i=1; i<=k; i++)
        F[i][1]=rez[i][1];
}
int main(){

    freopen("pod.in", "r", stdin);
    freopen("pod.out", "w", stdout);
    int i, j;
    int l, putere;
    scanf("%d%d%d",&n, &m, &k);
    for(i=1; i<=m; i++)
        scanf("%d", &poz[i]);
    m++; poz[m]=n+1;
    m++; poz[m]=0;
    sort(poz+1, poz+m+1);

    //dp-ultimele k valori, dp[k]-> val de pe pozitia 0/ poz interzise (dp[k]= 1 intial/0 pe urma)
    for(i=1; i<k; i++) dp[i]=0; dp[k]=1;

    for(l=2; l<=m; l++){

        putere=poz[l]-poz[l-1]-1;

        for(i=1; i<=k; i++)
            F[i][1]=dp[i];

        for(i=1; i<=k; i++)
            for(j=1; j<=k; j++)
                if(i+1==j) T[i][j]=1;
                else T[i][j]=0;
        T[k][1]=1; T[k][k]=1;
        for(i=2; i<k; i++)
                T[k][i]=0;

        ridica(T, putere);
        inmulteste(T, F) ;

        dp[k]=0;
        for(i=1; i<k; i++)
            dp[i]=F[i+1][1];
    }
    printf("%d", dp[k-1]);
    return 0;
}