Cod sursa(job #1853760)

Utilizator alexnekiNechifor Alexandru alexneki Data 22 ianuarie 2017 00:35:15
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
#include <iostream>
#include <bitset>

using namespace std;

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

bitset<radmax> ciur; //ciur[i] == true <=> composed number
int primes[radmax], nprimes;

void computeciur() {
  primes[0] = 2;
  nprimes = 1;
  for (int i = 3; i < radmax; i += 2) {
    if (ciur[i] == 0) {
      primes[nprimes] = i;
      nprimes++;
      if (1LL * i * i < radmax) {
        int j = i * i;
        while (j < radmax) {
          ciur[j] = 1;
          j += 2 * 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 effpower(int a, int b) {
  if (b == 0)
    return 1;
  else {
    int result = effpower(a, b >> 1);
    if ((b & 1) == 0)
      return (result * result) % modulo;
    else
      return (((result * result) % modulo) * a) % modulo;
  }
}

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 = (effpower(primes[i] % modulo, npow + 1) - 1) % modulo;
//      int invers2 = pow(primes[i] - 1, modulo - 2) % 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;

    int powerterm = (effpower(n % modulo, 1 + 1) - 1) % modulo;
//      int invers2 = pow(primes[i] - 1, modulo - 2) % modulo;
    gcd(invers, y, (n - 1) % modulo, modulo);
    if (invers <= 0)
      invers = modulo + invers % modulo;

    sumadiv = (((sumadiv * powerterm) % modulo) * invers) % modulo;
  }
  if (sumadiv <= 0) {
    sumadiv = modulo + sumadiv % modulo;
  }
  printf("%d %d\n", ndiv, sumadiv);
}

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;
}