Cod sursa(job #2240450)

Utilizator paul_danutDandelion paul_danut Data 13 septembrie 2018 14:11:14
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include <fstream>
#include <math.h>

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

using namespace std;

constexpr int MAXN = 1000001;


//(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 extended_euclid(long long a, long long b, long long &d, long long &x, long long &y)
{
    if( b==0 )
    {
        d = a;
        x = 1;
        y = 0;
    }
    else
    {
        extended_euclid(b, a%b, d, x, y);
        auto x0 =x;
        auto y0 =y;

        y = x0 - ( a / b ) * y0;
        x = y0;
    }
}

long long compute_modular_inverse(long long a, long long b)
{
    long long d = 0, x = 0, y = 0;

    extended_euclid(a, b, d, x, y);

    while(x < 1)
    {
        x += b;
    }

    return x;
}

void initialize(bool filter[])
{
    for(auto i=0; i<MAXN; ++i)
    {
        filter[i] = true;
    }
}

void buildData(bool filter[])
{
    for(auto i=2; i<=MAXN; ++i)
    {
        if(filter[i])
        {
            for(auto j=i+i; j<MAXN; j+=i)
            {
                filter[j] = false;
            }
        }
    }
}

void computeValues(long long &nr, long long &sum, long long nr_d, long long prime)
{
    auto mi = compute_modular_inverse(prime-1, 9973);
    auto prime_pow = ((long long)pow(prime, nr_d + 1)-1) % 9973;
    sum *= (prime_pow * mi) % 9973;
    nr *= nr_d + 1;
}

bool filter[MAXN];

int main()
{


    int t=0;
    long long x=0;
    long long int sum = 0;
    long long int nr = 0;

    initialize(filter);
    buildData(filter);

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

        if(x < MAXN && filter[x])
        {
            ++nr;
            sum += x;
        }
        else
        {
            for(auto i = 2; i < MAXN; ++i)
            {
                if(filter[i])
                {
                    auto nr_d = 0;
                    while( x % i == 0 )
                    {
                        ++ nr_d;
                        x /= i;
                    }


                    if(nr_d > 0)
                    {
                        computeValues(nr, sum, nr_d, i);
                    }
                }
            }
            if(x >= MAXN)
            {
                computeValues(nr, sum, 2, x);
            }
        }

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

        --t;
    }
}