Cod sursa(job #3201688)

Utilizator TheRomulusIvan Remus TheRomulus Data 9 februarie 2024 15:59:39
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.84 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <limits.h>
#include <chrono>
#include <numeric>

#include <vector>
#include <string>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <deque>  
#include <stack>
#include <queue>
#include <list>

using namespace std;

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

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb;
typedef vector<vb> vvb;
 
double EPS = 1e-9;
int INF = 1000000005;
long long INFF = 1000000000000000005LL;
double PI = acos(-1);

#define M 1000000007

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> T nxt() {
    T x;
    cin >> x;
    return x;
}

vector<ll> getPrimes(int n){
    vb isPrime(n + 1, 1);
    isPrime[0] = isPrime[1] = 0;
    for (int i = 2; i * i <= n; ++i) {
        if (isPrime[i]) {
            int multiple = 2 * i;
            while (multiple <= n) {
                isPrime[multiple] = 0;
                multiple += i;
            }
        }
    }

    vl primes;
    for(int i=2;i<=n;++i){
        if(isPrime[i]){
            primes.push_back(i);
        }
    }

    return primes;
}

void recursiveGCD(ll& x, ll& y, ll a, ll b)
{
    if (!b)
        x = 1, y = 0;
    else
    {
        recursiveGCD(x, y, b, a % b);
        ll aux = x;
        x = y;
        y = aux - y * (a / b);
    }
}

/*
* Compute B such that A * B = 1 % N
*/
ll computeModularInverse(ll A,ll N) {
    ll inv = 0, ins;

    recursiveGCD(inv, ins, A, N);

    if (inv <= 0)
        inv = N + inv % N;

    return inv;
}

void Solve(const vl& primes){
    ll n,x,noDivisors=1,sumDivisors=1,m=9973;
    fin>>n;

    x=n;
    for(auto p:primes){
        if(x==1){
            break;
        }

        if(p*p>x){
            noDivisors*=2;
            sumDivisors=sumDivisors*(x+1)%m;
            break;
        }

        ll nr=0,val=1;
        while(x%p==0){
            ++nr;
            x/=p;
            val*=p;
        }

        if(nr){
            noDivisors*=(nr+1);
            sumDivisors=sumDivisors*(val*p-1)%m*computeModularInverse(p-1,m)%m;
        }
    }

    fout<<noDivisors<<' '<<sumDivisors<<'\n';
}

int main(){
    // freopen(".in", "r", stdin);
    // freopen(".out", "w", stdout);

    // ios_base::sync_with_stdio(false);
    // cin.tie(NULL);

    // std::string file="FILE";
    // std::ifstream in(file+".in");
    // std::streambuf *finbuf = std::fin.rdbuf(); //save old buf
    // fin.rdbuf(in.rdbuf()); //redirect std::fin
    
    // std::ofstream out(file+".out");
    // std::streambuf *foutbuf = std::fout.rdbuf(); //save old buf
    // fout.rdbuf(out.rdbuf()); //redirect std::fout

    vl primes=getPrimes(1e6);
    int t;
    fin>>t;
    while(t--){
        Solve(primes);
    }

    // std::fin.rdbuf(finbuf);   //reset to standard input again
    // std::fout.rdbuf(foutbuf); //reset to standard output again

    return 0;
}