Cod sursa(job #2243261)

Utilizator paul_danutDandelion paul_danut Data 20 septembrie 2018 10:47:06
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 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[100000];

//(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(int primes[], int &K)
{
    bitset <MAXN> filter;

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

    K = 0;
    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;
    int K;

    findPrimes(primes, K);

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

        for(int i = 0; i < K && x > 1; ++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 = nr*2 + 1;
            sum = (1LL * sum * ((x + 1)%9973)) % 9973;
        }

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

        --t;
    }
}