Cod sursa(job #2243270)

Utilizator paul_danutDandelion paul_danut Data 20 septembrie 2018 11:03:19
Problema Suma si numarul divizorilor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <fstream>
#include <math.h>
#include <iostream>
#include <bitset>

std::ifstream f("ssnd.in");
std::ofstream g("ssnd.out");

using namespace std;

constexpr int MAXN = 1000001;

int primes[100001];
int K = 0;

//(a - b) mod p = ((a mod p - b mod p) + p) mod p
//(a / b) mod p = ((a mod p) * (b^(-1) mod p)) mod p
//Where b^(-1) mod p is the modular inverse of b mod p. For p = prime, b^(-1) mod p = b^(p - 2) mod p

void findPrimes()
{
    bitset <MAXN> filter;

    for(int i=0; i<MAXN; ++i)
    {
        filter[i] = 1;
    }
    for(int i=2; i<MAXN; ++i)
    {
        if(filter[i])
        {
            primes[K] = i;
            ++K;

            for(int j=i+i; j<MAXN; j+=i)
            {
                filter[j] = 0;
            }
        }
    }
}

inline int power(int n, int p, int mod)
{
    int r = 1;

    while( p != 1 )
    {
        if( p % 2 ==1 )
        r = (1LL * n * r) % mod;
        n = (1LL * n * n) % mod;
        p = p / 2;
    }

    return ( 1LL * n * r ) % mod;
}

void computeValues(int &nr, int &sum, int nr_d, int prime)
{
    int mi = power(prime-1, 9971, 9973);                 ///For p = prime, b^(-1) mod p = b^(p - 2) mod p
    int prime_pow = power(prime, nr_d + 1, 9973) - 1;

    sum = (1LL * sum * prime_pow * mi) % 9973;
    nr *= nr_d + 1;
}

int main()
{
    int t=0;
    long long x=0;
    int sum = 0;
    int nr = 0;

    findPrimes();

    f>>t;
    while(t > 0)
    {
        f >> x;
        sum = 1;
        nr = 1;

        for(int i = 0; i < K &&  1LL * primes[i] * primes[i] <= x; ++i)
        {
            auto nr_d = 0;
            while( x % primes[i] == 0 )
            {
                ++ nr_d;
                x /= primes[i];
            }

            if(nr_d > 0)
            {
                computeValues(nr, sum, nr_d, primes[i]);
            }
        }
        if(x > 1)
        {
            ++nr;
            computeValues(nr, sum, 1, x);
        }

        g << nr << ' ' << sum <<'\n';

        --t;
    }
}