Cod sursa(job #2145276)

Utilizator SolcanMihaiSolcan Mihai Andrei SolcanMihai Data 27 februarie 2018 11:23:32
Problema Invers modular Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <set>

using namespace std;

const int MOD = 9973;

int n;
int x;
int divizori[12];
int divizorix[12];
long long factoriale[15];
int nrDivizori = 0;
long long solx = 0;
long long sol = 1;

set<vector<int> > S;

pair<int, int> q(int a, int b){
    if(b == 0){
        return {1, 0};
    }
    else{
        pair<int, int> x = q(b, a % b);
        return {x.second, x.first - (a / b) * x.second};
    }
}

int inversModular(int x){
    int rez = q(x, MOD).first;

    while(rez < 0){
        rez += MOD;
    }

    return rez;
}

void computeFactorials(){
    factoriale[0] = 1;
    factoriale[1] = 1;
    for(int i = 2; i < 15; i++){
        factoriale[i] = factoriale[i - 1] * i;
    }
}

bool precomputeDiv(){
    int x = ::x;

    for(int i = 2; i <= x; i++){
        if(i >= 10){
            printf("%d", 0);
            return false;
        }

        while(x % i == 0){
            x /= i;
            nrDivizori++;
            divizori[i]++;
        }
    }

    return true;
}

void solve(){
    vector<int> tmpx;

    for(int i = 2; i < 10; i++){
        tmpx.push_back(divizori[i]);
    }

    if(S.find(tmpx) != S.end()){
        return;
    }

    S.insert(tmpx);

//    for(int i = 2; i < 10; i++){
//        printf("%d", divizori[i]);
//    }
//
//    printf("\n");

    for(int i = n - nrDivizori + 1; i <= n; i++){
        sol *= i;
        sol %= MOD;
    }

    for(int i = 2; i < 10; i++){
        sol *= inversModular(factoriale[divizori[i]]);
        sol %= MOD;
    }
}

void compute(int x, int last){
    sol = 1;
    solve();
    solx += sol;

    solx %= MOD;

    bool toReset = false;

    for(int i = 2; i <= 4; i++){
        if(divizori[i] > 0){
            divizori[i]--;
        }
        else{
            continue;
        }

        for(int j = i; j <= 4; j++){
            if(divizori[j] > 0 && i * j < 10){
                divizori[j]--;
                divizori[i * j]++;
                x = 1;
                nrDivizori--;
                compute(1, j);
                nrDivizori++;
                divizori[i * j]--;
                divizori[j]++;
            }
        }

        divizori[i]++;
    }

}

int main()
{
    freopen("numere6.in", "r", stdin);
    freopen("numere6.out", "w", stdout);

    scanf("%d %d", &n, &x);
    computeFactorials();
    if(precomputeDiv() == false){
        return 0;
    }

    for(int i = 2; i < 10; i++){
        divizorix[i] = divizori[i];
    }

    compute(1, 2);

    for(int i = 2; i < 10; i++){
        if(divizori[i] != divizorix[i]){
            cerr << "Mozzart";
        }
    }

    printf("%lld", solx % 9973);

    return 0;
}