Cod sursa(job #2025181)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 21 septembrie 2017 23:51:32
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <iostream>
#include <fstream>
#include <bitset>
#include <vector>
#define LIM 1000000
#define MOD 9973

using namespace std;

bitset<LIM> mark;
vector<int> primes;

void ciur() {

    for (int i = 3; i * i <= LIM; i += 2) {

        if (!mark.test(i)) {

            for (int j = i * i; j <= LIM; j += 2 * i)
                mark.set(j);
        }
    }

    primes.push_back(2);
    for (int i = 3; i < LIM; i += 2)
        if (!mark.test(i))
            primes.push_back(i);
}

void gcd(int a, int b, int& x, int& y) {

    if (b == 0) {

        x = 1;
        y = 0;

    } else {

        gcd(b, a % b, x, y);
        int aux = y;
        y = x - (a / b) * y;
        x = aux;
    }
}

int pow_MOD(long long int a, long long int b) {

    long long int res = 1;
    for (int i = 0; (1 << i) <= b; i++) {

        if (b & (1 << i))
            res = (res * a) % MOD;
        a = (a * a) % MOD;
    }
    return res;
}

int main() {

    int t, x, y, nr, pos;
    long long int n, nr_d, sum;
    ifstream in("ssnd.in");
    ofstream out("ssnd.out");

    ciur();

    for (in >> t; t; --t) {

        in >> n;

        pos = 0;
        sum = nr_d = 1;

        while (primes[pos] * primes[pos] <= n) {

            nr = 0;
            while (n % primes[pos] == 0) {

                nr++;
                n /= primes[pos];
            }

            if (nr > 0) {

                /// divisor number update
                nr_d = nr_d * (nr + 1) * 1LL;
                /// divisor sum update
                gcd(primes[pos] - 1, MOD, x, y); /// primes * x + MOD * y = 1
                if (x <= 0)
                    x = MOD + x % MOD;
                sum = (sum * (((pow_MOD(primes[pos], nr + 1) - 1) * 1LL * x) % MOD)) % MOD;
            }

            if (++pos >= (signed)primes.size())
                break;
        }

        if (n != 1) {

            nr_d *= 2LL;
            sum = (sum * (n + 1)) % MOD;
        }

        out << nr_d << " " << sum << "\n";
    }

    in.close();
    out.close();
    return 0;
}