Cod sursa(job #2039877)

Utilizator raduzxstefanescu radu raduzx Data 15 octombrie 2017 00:32:38
Problema Pod Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <fstream>
#include <algorithm>
using namespace std;

int n,m,k;
int a[30][30],identitate[30][30],b[1003],nl[30][30],actual[30],rest[30][30];
ifstream f("pod.in");
ofstream g("pod.out");
#define mod 9901
void copie(int m1[30][30],int m2[30][30])
{
    int i,j;
    for(i=1;i<=k;i++)
        for(j=1;j<=k;j++)
            m1[i][j]=m2[i][j]%mod;
}
void inm(int m1[30][30],int m2[30][30])
{
    int m3[30][30],i,q,j;
    copie(m3,nl);
    for(i=1;i<=k;i++)
        for(j=1;j<=k;j++)
            for(q=1;q<=k;q++)
                m3[i][j]+=m1[i][q]*m2[q][j];
    copie(m1,m3);
}
void inm2(int m1[30],int m2[30][30])
{
    int m3[30],i,j;
    for(i=0;i<=k;i++)
        m3[i]=0;
    for(i=0;i<k;i++)
        for(j=1;j<=k;j++)
            m3[i]+=m1[j-1]*m2[j][i+1];
    for(i=0;i<k;i++)
        m1[i]=m3[i]%mod;
}
int main()
{
    int i,j,w,t;
    f>>n>>m>>k;
    for(i=1;i<=m;i++)
        f>>b[i];
    sort(b+1,b+m+1);
    for(i=2;i<=k;i++)
        {a[i][i-1]=1;identitate[i][i]=1;}
    a[1][k]=a[k][k]=1;
    copie(rest,identitate);
    if(b[1]<k)
    {
        for(i=1;i<b[1];i++)
            actual[i]=1;
        for(i=b[1]+1;i<=k;i++)
            actual[i]=0;
    }
    actual[0]=1;
    i=1;
    while(b[i]<k)
    {
        i++;
    }
    int exp,o[30][30];
    b[i-1]=k-1;
    for(;i<=m;i++)
    {
        exp=b[i]-b[i-1];

        if(exp>1)
        {
            copie(rest,identitate);
            copie(o,a);
            while(exp>1)
            {
                if(exp%2==1)
                    inm(rest,o);
                inm(o,o);
                exp/=2;
            }
            inm(o,rest);
            inm2(actual,o);
        }
        for(j=0;j<k;j++)
            actual[j]=actual[j+1];
        actual[k-1]=0;
    }
    exp=n-b[m];
    if(exp>1)
    {
        copie(rest,identitate);
        copie(o,a);
        while(exp>1)
        {
            if(exp%2==1)
                inm(rest,o);
            inm(o,o);
            exp/=2;
        }
        inm(o,rest);
        inm2(actual,o);
    }
    g<<actual[k-1];
    return 0;
}