Cod sursa(job #1494225)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 30 septembrie 2015 20:50:53
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
 
constexpr int mod = 9973;
 
pair<int, int> euclid_extins(const int a, const int b){
    if(b == 0){
        return {1, 0}; }
    const auto tmp = euclid_extins(b, a%b);
    return {tmp.second, tmp.first - (a/b) * tmp.second}; }
 
int exp(int e, int x){
    int rez = 1;
    e %= mod;
    for( ; x; x/=2, e *= e, e %= mod){
        if(x&1){
            rez *= e;
            rez %= mod; } }
    return rez; }
 
int invers_modular(const int x){
    // x*y % mod = 1
    // x*y + mod*p = 1
    const auto tmp = euclid_extins(x, mod);
    return (tmp.first%mod+mod)%mod; }
 
vector<int> calc_primes(const int maxn){
    vector<int> primes;
    vector<bool> e_prim(maxn/2 + 1, true);
    primes.push_back(2);
    for(long long i = 3; i <= maxn; i += 2){
        if(e_prim[i/2]){
            primes.push_back(i);
            for(long long j = i*i; j <= maxn; j += 2*i){
                e_prim[j/2] = false; } } }
    return primes; }
 
void ssnd(long long a, long long& nr_div, long long& s_div){
	const long long a_init = a;
    const static vector<int> primes = calc_primes(1000000);
    nr_div = s_div = 1;
    long long s_div_sus = 1, s_div_jos = 1;
    for(const auto p : primes){
        if(p > a || p*p > a_init){
            break; }
        int n = 0;
        for( ; a%p == 0; a /= p, ++n);
        if(n > 0){
            nr_div *= (n+1);
 
            s_div_sus *= (exp(p, n+1) - 1);
            s_div_sus %= mod;
            s_div_jos *= (p-1);
            s_div_jos %= mod; } }
	if(a == 1){
		s_div = (s_div_sus * invers_modular(s_div_jos))%mod; }
	else{
		nr_div = 2;
		s_div = (a+1)%mod; } }
 
int main(){
    ifstream f("ssnd.in");
    ofstream g("ssnd.out");
    int t;
    f >> t;
    for(int i = 0; i < t; ++i){
        long long x, nr_div, s_div;
        f >> x;
        ssnd(x, nr_div, s_div);
        g << nr_div << ' ' << s_div << '\n'; }
    return 0; }