Cod sursa(job #3161056)

Utilizator leelcheeseCiovnicu Denis leelcheese Data 25 octombrie 2023 17:26:39
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.79 kb
#include <bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define nmax 1000100
#define MOD 9973
//#define fin cin
//#define fout cout
using namespace std;

ifstream fin("ssnd.in");
ofstream fout("ssnd.out");

int p[80000], k;
bitset <1000101> a;

/**
12 = 2^2 * 3^1
sdiv= 1 + 2^1 + 2^2 + 3^1 + 2^1 * 3^1 + 2^2 * 3^1 = (1 + 2^1 + 2^2)(1 + 3^1)

f^(k + 1) - 1
------------- = (f^(k + 1) - 1) % MOD * invmodular(f-1, MOD - 2)
    f - 1
**/

void Ciur(int n)
{
    for (int i = 3; i * i <= n; i += 2)
        if (a[i] == 0)
            for (int j = i * i; j <= n; j += 2 * i)
                a[j] = 1;
    p[1] = 2; k = 1;
    for (int i = 3; i <= n; i += 2)
        if (a[i] == 0)
            p[++k] = i;
}

long long Put(long long x, int exp)
{
    if (exp == 0)
        return 1;
    if (exp % 2 != 0)
        return x * Put(x, exp - 1) % MOD;
    long long P = Put(x, exp / 2);
    return P * P % MOD;
}

// return nr div a lui n
void NrDiv(long long n, int &cnt, long long &sumdiv)
{
    int f, e, putere;
    cnt = 1; sumdiv = 1;
    for (int i = 1; 1ll * p[i] * p[i] <= n; i++)
    {
        f = p[i]; e = 0;
        while (n % f == 0)
        {
            n /= f;
            e++;
        }
        if (e > 0)
        {
            cnt *= (e + 1);
            putere = (Put(f, e + 1) - 1 + MOD) % MOD;
            putere = putere * Put(f - 1, MOD - 2) % MOD;
            sumdiv = (sumdiv * putere) % MOD;
        }
    }
    if (n > 1)
    {
        cnt *= 2;
        sumdiv = sumdiv * (n + 1) % MOD;
    }
}

int main()
{
    Ciur(nmax);
    int nrdiv, t;
    long long sdiv, x;
    fin >> t;
    while (t--)
    {
        fin >> x;
        NrDiv(x, nrdiv, sdiv);
        fout << nrdiv << " " << sdiv << "\n";
    }
    return 0;
}