Cod sursa(job #2516127)

Utilizator SoranaAureliaCatrina Sorana SoranaAurelia Data 30 decembrie 2019 13:47:28
Problema Pod Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>

#define KMAX 25
#define MMAX 1005
#define MOD 9901
using namespace std;

ifstream f("pod.in");
ofstream g("pod.out");

class Mat{
public:
    int n, m;
    int a[KMAX][KMAX];
    void init(int n1, int m1){
        n=n1;
        m=m1;
        for(int i=0; i<n1; i++)
            for(int j=0; j<m1; j++)
                a[i][j]=0;
    }
    void setUnit(){
        for(int i=0; i<n; i++)
                a[i][i]=1;
    }
    Mat &operator=(const Mat &other){
        n=other.n;
        m=other.m;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                a[i][j] = other.a[i][j];
        return *this;
    }
    Mat operator*(const Mat &other){
        Mat rez;
        rez.init(n, other.m);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                for(int k=0;k<other.m; k++)
                    rez.a[i][j] = (rez.a[i][j] + (1LL*a[i][k]*other.a[k][j])%MOD)%MOD;
        return rez;
    }

    Mat pow(int power, Mat ma){
        Mat rez;
        rez.init(ma.n, ma.m);
        rez.setUnit();

        while(power){
            if(power%2 == 1){
                power --;
                rez = rez*ma;
            }
            power/=2;
            ma = ma*ma;
        }
        return rez;
    }

};

int n, m, k;
int x;
vector<int> pozitiilipsa;
int fr[KMAX];

int poz;
Mat dp, val;

void formInit(){
    int x;
    for(int i=1; i<=m; i++){
        f>>x;
        if(x<=k)
            fr[x-1] ++;
        else if(x == n){
            g<<"0";
            exit(0);
        }
        else pozitiilipsa.push_back(x);
    }
    pozitiilipsa.push_back(n);
    sort(pozitiilipsa.begin(), pozitiilipsa.end());

    if(fr[0] == 0)
        val.a[0][0]=1;
    for(int i=1; i<k; i++){
        if(fr[i] == 0)
            val.a[0][i] += val.a[0][i-1];
    }
    if(fr[k-1] == 0)
        val.a[0][k-1]++;
    dp.a[0][k-1] = dp.a[k-1][k-1] = 1;
    for(int i=1; i<k; i++)
        dp.a[i][i-1] = 1;
}

int rez(){
    int u = k;
    for(auto &i:pozitiilipsa){
        int dif = i - u;
        u = i;
        val = val*dp.pow(dif, dp);
        if(i!=n)
            val.a[0][k-1] = 0;
    }

    return val.a[0][k-1];

}
int main()
{
    f>>n>>m>>k;
    dp.init(k, k);
    val.init(1, k);
    formInit();
    g<<rez();
    return 0;
}