Cod sursa(job #2040049)

Utilizator raduzxstefanescu radu raduzx Data 15 octombrie 2017 13:05:58
Problema Pod Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <fstream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,m,k;
ll 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(ll m1[30][30],ll m2[30][30])
{
    ll i,j;
    for(i=1;i<=k;i++)
        for(j=1;j<=k;j++)
            m1[i][j]=m2[i][j]%mod;
}
void inm(ll m1[30][30],ll m2[30][30])
{
    ll 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(ll m1[30],ll m2[30][30])
{
    ll 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()
{
    ll 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;
    }
    else
        for(i=0;i<k;i++)
            actual[i]=1;
    actual[0]=1;
    i=1;
    while(b[i]<k)
    {
        i++;
    }
    ll 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;
}