Cod sursa(job #2243037)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 19 septembrie 2018 20:31:56
Problema Pod Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <fstream>
#include <algorithm>
#define mod 9901
using namespace std;
fstream f1("pod.in", ios::in);
fstream f2("pod.out", ios::out);
int n, m, k, poz[1005];
long long dp[1005], F[2][30], T[30][30];
void inm(long long a[30][30], long long b[30][30]){

    long long rez[30][30];
    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];
                    rez[i][j]%=mod;
                }
            }
    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            a[i][j]=rez[i][j];
}
void ridica(long long T[30][30], int p){

    long long rez[30][30];
    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%2==1) inm(rez, T);
        inm(T,T);
        p/=2;
    }
    for(int i=1; i<=k; i++)
        for(int j=1; j<=k; j++)
            T[i][j]=rez[i][j];
}
int main(){

    int i, j, l;
    f1>>n>>m>>k;
    for(i=1; i<=m; i++)
        f1>>poz[i];
    m++; poz[m]=n+1;
    m++; poz[m]=0;
    sort(poz+1, poz+m+1);
    dp[0]=1;
    for(l=2; l<=m; l++)
        if(poz[l-1]+k-1 <=poz[l])  //dp[i]=dp[i-1]+dp[i-k]
        {
            for(j=poz[l-1]+1; j<poz[l]; j++)
            {
                dp[j]=dp[j-1];
                if(j-k>poz[l-1])
                    dp[j]+=dp[j-k];
                dp[j]%=mod;
            }
            dp[poz[l]]=dp[poz[l]-1];
        }
        else
        {
            F[1][1]=dp[poz[l-1]];
            for(i=2; i<=k; i++){

                dp[poz[l-1]+i-1]+=dp[poz[l-1]+i-2];
                if(i-k-1>0)
                    dp[poz[l-1]+i-1]+=dp[poz[l-1]+i-k-1];
                dp[poz[l-1]+i-1]%=mod;
                F[i][1]=dp[poz[l-1]+i-1];
            }
            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, poz[l]-1); //T=T^(poz[l]-1)
            inm(F,T); //F=F*T
            dp[poz[l]]=F[1][1]; //F[1][1]=dp[poz[l]-1];
        }
    f2<<dp[n+1];//=dp[n]
    return 0;
}