Cod sursa(job #2485976)

Utilizator DysKodeTurturica Razvan DysKode Data 2 noiembrie 2019 10:57:58
Problema Pod Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("pod.in");
ofstream fout("pod.out");
long long v[1010];
int D[100010], cur;
long long indici[100010];
long long n, m , p;
const int modu = 9901;

struct matrix{
    int m[21][21];
    matrix(){
        for(int i = 0 ; i < 21 ; i++){
            for(int j = 0 ; j < 21 ; j++){
                m[i][j] = 0;
            }
        }
    }

    matrix operator*(matrix b){
        matrix c;
        for(int k = 0 ; k < p ; k++){
            for(int i = 0 ; i < p ; i++){
                for(int j = 0 ; j < p ; j++){
                    c.m[i][j] = (c.m[i][j] + m[i][k]*b.m[k][j]) % modu;
                }
            }
        }
        return c;
    }

    void print(){
        for(int i = 0 ; i < p ; i++){
            for(int j = 0 ; j < p ; j++){
                cout << m[i][j] << ' ';
            }
            cout << '\n';
        }
    }
};

matrix O, I, a, b, c;

matrix matPow(matrix m, long long int put){
    if( put == 0 ) return I;
    if( put == 1 ) return m;
    matrix aux = matPow(m, put / 2);
    aux = aux * aux;
    if(put % 2 == 1)
        aux = aux * m;
    return aux;
}

set<long long> sit;

int main()
{
    fin >> n >> m >> p;

    for(int i = 0 ; i < p ; i++){
        I.m[i][i] = 1;
    }
    for(int i = 0 ; i < p - 1 ; i++){
        c.m[i+1][i] = 1;
        c.m[i][p-1] = 1;
    }
    c.m[p-1][p-1] = 1;

    for(int i = 1 ; i <= m ; i++){
        fin >> v[i];
        sit.insert(v[i]);
    }
    m++;
    v[m] = n + 1;
    sit.insert(v[m]);
    D[0] = 1;
    for(int i = 1 ; i <= p ; i++){
        cur++;
        indici[cur] = i;
        for(int j = i - 1 ; j >= 0 ; j--){
            D[i] += D[j];
        }
        if(sit.find(i) != sit.end()){
            D[i] = 0;
        }
        D[i] %= modu;
    }
    for(int sc = 1 ; sc <= m ; sc++){
        if(v[sc]-indici[cur] <= p){
            //cout << cur << ' ' << indici[cur] << ' ' << v[sc] << "jos\n";
            while(indici[cur] <= v[sc]+p+1){
                for(int j = 0 ; j < p ; j++){
                    D[ cur + 1 ] += D[cur - j];
                }
                D[cur + 1] %= modu;
                indici[cur + 1] = indici[cur] + 1;
                cur++;
                if(sit.find(indici[cur]) != sit.end()){
                    D[cur] = 0;
                }
            }
        } else {
//            cout << cur << ' ' <<  indici[cur] << ' ' << v[sc] << "mat\n";
            a = O;
            for(int i = 0 ; i < p ; i++){
                a.m[0][p-1-i] = D[cur-i];
            }
//            cout << "a\n";
//            a.print();
            long long x = v[sc] - indici[cur] - 1;
//            cout << "x=" << x<<'\n';
            b = c;
 //           cout << "b\n";
//            b.print();
            b = matPow(b, x);
//            cout << "b\n";
//            b.print();
            a = a * b;
//            cout << "a\n";
//            a.print();
            for(int i = 0 ; i < p ; i++){
                D[cur+i+1] = a.m[0][i];
                indici[cur+i+1] = indici[cur] + x - (p-1-i);
            }
            sc--;
            cur += p;
        }
    }

    /*
    for(int i = 0 ; i <= cur ; i++){
        cout << D[i] << '\t';
    }
    cout << '\n';
    for(int i = 0 ; i <= cur ; i++){
        cout << indici[i] << '\t';
    }
    cout<< '\n';
*/
    for(int i = cur ; i >= 0 ; i--){
        if(indici[i]==n){
            fout << D[i];
            return 0;
        }
    }
    
}