Cod sursa(job #1853443)

Utilizator alexnekiNechifor Alexandru alexneki Data 21 ianuarie 2017 19:53:31
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <cassert>

using namespace std;

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

int const radmax = 1000001;
int const nmax = 1001;
int const modulo = 9973;

int ciur[radmax]; //ciur[i] == true <=> composed number
int nfactor, power[nmax];
int factor[nmax];
int primes[radmax], nprimes;

void computeciur() {
  ciur[0] = ciur[1] = 1;
  ciur[2] = ciur[3] = 0;
  primes[0] = 2;
  primes[1] = 3;
  nprimes = 2;
  for (int i = 4; i < radmax; i += 2) {
    ciur[i] = 1;
  }
  for (int i = 5; i < radmax; i += 2) {
    if (ciur[i] == 0) {
      primes[nprimes] = i;
      nprimes++;
      long long j = ((long long) i) * i;
      while (j < radmax) {
        ciur[j] = 1;
        j += i;
      }
    }
  }
}

void decompose(long long n) {
  nfactor = 0;

  int i = 0;
  while (i < nprimes && primes[i] <= sqrt(n)) {
    if (n % primes[i] == 0) {
      factor[nfactor] = primes[i] % modulo;
      int npow = 0;
      while (n % primes[i] == 0) {
        npow++;
        n = n / primes[i];
      }
      power[nfactor] = npow;
      nfactor++;
    }
    i++;
  }

  if (1 < n) {
    factor[nfactor] = n % modulo;
    power[nfactor] = 1;
    nfactor++;
  }
//debug
//  for (int i = 0; i < nfactor; i++) {
//    cout << factor[i] << "^" << power[i] << endl;
//  }
}

int effpower(int a, int b) {
//  cout << a << " " << b << " -> ";
  if (b == 0)
    return 1;
  else if (b == 1)
    return a;
  else if ((b & 1) == 0) {
    int result = effpower(a, b >> 1);
//    cout << a << " " << b << " " << result << endl;
    return (result * result) % modulo;
  } else {
    int result = effpower(a, b >> 1);
    return (((result * result) % modulo) * a) % modulo;
  }
}

int numdiv() {
  int result = 1;
  for (int i = 0; i < nfactor; i++) {
    result *= (power[i] + 1);
  }
  return result;
}

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

int sumdiv() {
  int sd = 1, modif1;
  long invers = 0, y;

  for (int i = 0; i < nfactor; i++) {
    modif1 = effpower(factor[i], power[i] + 1) + modulo - 1;
    gcd(invers, y, factor[i] - 1, modulo);
    if (invers <= 0)
      invers = modulo + invers % modulo;
    sd = (((sd * modif1) % modulo) * invers) % modulo;
//    cout << effpower(factor[i], power[i] + 1) << " " << modif1 << " " << modif2 << " " << sd << endl;
  }
  return sd;
}

int main() {
//  cout << effpower(2, 4) << endl;
  computeciur();

  int t;
  in >> t;
  for (int i = 0; i < t; i++) {
    long long n;
    in >> n;
    decompose(n);
    int nd = numdiv();
    int sd = sumdiv();
    out << nd << " " << sd << endl;
  }
  return 0;
}