Cod sursa(job #2069997)

Utilizator danny794Dan Danaila danny794 Data 19 noiembrie 2017 04:28:19
Problema Suma si numarul divizorilor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bitset>
#include <cstdint>
#include <fstream>
#include <vector>

#define PMAX 1005
#define MOD 9973

std::ifstream cin("ssnd.in");
std::ofstream cout("ssnd.out");
std::bitset<PMAX * PMAX> isPrime;
std::vector<int64_t> primes;

void findPrimes() {
  /* Mark all numbers as prime. */
  isPrime.set();
  int64_t noPrimes = 1; // count 2 as well
  for (int64_t i = 3; i < PMAX; i += 2) {
    if (isPrime[i]) {
      noPrimes++;
      for (int64_t j = i * i; j < isPrime.size(); j += i) {
        isPrime[j] = false;
      }
    }
  }
  primes.reserve(noPrimes);
  primes.emplace_back(2);
  for (int64_t i = 3; i < PMAX; i += 2) {
    if (isPrime[i]) {
      primes.emplace_back(i);
    }
  }
}

std::pair<int64_t, int64_t> getPower(int64_t& n, int64_t p) {
  std::pair<int64_t, int64_t> result;
  result.second = 1;
  while (n % p == 0) {
    n /= p;
    result.first++;
    result.second *= p;
  }
  return result;
}

void solve(int64_t n) {
  int64_t currentSum = 1;
  int64_t noDivisors = 1;
  std::pair<int64_t, int64_t> power;
  size_t idx = 0;
  while (n > 1 && idx < primes.size()) {
    auto p = primes[idx];
    if (n % p == 0) {
      power = getPower(n, p);
      noDivisors *= (1 + power.first);
      currentSum = currentSum * ((power.second * p - 1) / (p - 1)) % MOD;
    }
    idx++;
  }
  if (n > 1) {
    /* n is prime */
    noDivisors *= 2;
    currentSum = currentSum * (n + 1) % MOD;
  }
  cout << noDivisors << " " << currentSum << "\n";
}

int main() {
  int64_t n, tests;
  findPrimes();
  cin >> tests;
  while (tests--) {
    cin >> n;
    solve(n);
  }
  return 0;
}