Cod sursa(job #2039894)

Utilizator raduzxstefanescu radu raduzx Data 15 octombrie 2017 00:51:02
Problema Pod Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.14 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;
    identitate[1][1]=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 and b[i]<n;i++)
    {
        exp=b[i]-b[i-1]-1;
        if(exp)
        {
        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;
    }
    if(i>=m) i=m;
    if(b[m]<n)
    {
        exp=n-b[m];
        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];
    }
    else
        g<<0;
    return 0;
}