Cod sursa(job #1463647)

Utilizator petru.cehanCehan Petru petru.cehan Data 21 iulie 2015 13:56:36
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <iostream>
#include <fstream>

using namespace std;

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

bool ciur [1000001] ;
long long t , n ;

int primes [100000] , nr ;

void Eratostene ()
{
    for ( int i = 2 ; i < 1000005 ; ++ i )
    {
        if ( ciur [i] == 0 )
        {
            primes [ ++ nr ] = i ;

            for ( int j = i + i ; j < 1000005 ; j += i )
                  ciur [j] = 1;
        }
    }

}

int pow ( int x , int p ) // fast expo
{
    int rez = 1 ;
    x %= 9973 ;

    for ( ; p ; p >>= 1 )
    {
        if ( p & 1 )
        {
            rez *= x;
            rez %= 9973 ;
        }

        x *= x ;
        x %= 9973 ;
    }

    return rez;
}

void CalculSumaSiDivizori ( int n )
{
    int sum_diviz = 1 , nr_diviz = 1 , nr_aux , copie = n ;

    for ( int i = 1 ; primes [i] * primes [i] <= copie && i <= nr ; ++ i )
          {
              if ( copie % primes [i] ) continue ;

              nr_aux = 0 ;
              while ( copie % primes [i] == 0 )
                {
                       ++ nr_aux ;
                       copie /= primes [i] ;
                }

              nr_diviz *= ( nr_aux + 1 ) ;

              int p1 = ( pow ( primes [i] , nr_aux + 1 ) - 1 ) % 9973 ;
              int p2 = pow ( primes [i] - 1, 9973 - 2 ) % 9973 ;
              sum_diviz = ((( sum_diviz * p1 ) % 9973 ) * p2 ) % 9973 ;
          }

    if ( copie > 1 )
    {
       nr_diviz *= ( 1 + 1 ) ;
       sum_diviz = ( 1LL * sum_diviz * ( copie + 1 ) % 9973 ) ;
    }

    fout << nr_diviz << " " << sum_diviz << "\n" ;
}

int main()
{
    Eratostene () ;
    for ( fin >> t ; t ; -- t )
         fin >> n , CalculSumaSiDivizori ( n ) ;

    return 0;
}