Cod sursa(job #1853550)

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

using namespace std;

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

int ciur[radmax]; //ciur[i] == true <=> composed number
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 gcd(int &x, int &y, int a, int 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 pow(int x, int p) {
  int rez = 1;
  x %= modulo;

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

    x *= x;
    x %= modulo;
  }

  return rez;
}

void decompose(long long n) {
  int invers, y;
  int ndiv = 1, sumadiv = 1;

  int i = 0;
  while (i < nprimes && (primes[i] * primes[i] <= n)) {
    if (n % primes[i] == 0) {
      int npow = 0;
      while (n % primes[i] == 0) {
        npow++;
        n /= primes[i];
      }

      ndiv *= npow + 1;

      int powerterm = (pow(primes[i], npow + 1) - 1) % modulo;
      gcd(invers, y, primes[i] - 1, modulo);
      if (invers <= 0)
        invers = modulo + invers % modulo;

      sumadiv = (((sumadiv * powerterm) % modulo) * invers) % modulo;
    }
    i++;
  }

  if (1 < n) {
    ndiv *= 2;
    sumadiv = (1LL * sumadiv * (n + 1)) % modulo;
  }

  printf("%d %d\n", ndiv, sumadiv);
//debug
//  for (int i = 0; i < nfactor; i++) {
//    cout << factor[i] << "^" << power[i] << endl;
//  }
}

int main() {
  freopen("ssnd.in", "rt", stdin);
  freopen("ssnd.out", "wt", stdout);

  computeciur();

  int t;
  scanf("%d", &t);
  for (int i = 0; i < t; i++) {
    long long n;
    scanf("%lld", &n);
    decompose(n);
  }
  return 0;
}