Cod sursa(job #1480103)

Utilizator salam1Florin Salam salam1 Data 2 septembrie 2015 04:58:11
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int NMAX = 1000505;
const int MOD = 9973;

struct primeFactorInfo {
  ll p, overAll;
  int exp;
};

int tests, r, invMod[MOD], E2[MOD];
ll n, P[NMAX];
bool notPrime[NMAX];

struct solution {
  ll noDivs, sumDivs;
};

void prepare() {
  for (int i = 2; i * i < NMAX; i++)
    if (!notPrime[i]) {
      for (int j = i * i; j < NMAX; j += i)
        notPrime[j] = 1;
    }

  for (int i = 2; i < NMAX; i++)
    if (!notPrime[i])
      P[++r] = i;

  E2[0] = 1;
  for (int i = 1; i < MOD; i++) {
    E2[i] = E2[i - 1] * 2;
    if (E2[i] >= MOD) E2[i] -= MOD;
  }

  for (int i = 0; i < MOD; i++) {
    invMod[E2[i]] = E2[MOD - 1 - i];
  }
}

vector<primeFactorInfo> decompose(ll n) {
  vector<primeFactorInfo> sol;
  for (int i =  1; 1LL * P[i] * P[i] <= n; i++)
    if (n % P[i] == 0) {
      int exp = 0;
      ll overAll = 1;
      while (n % P[i] == 0) {
        n /= P[i];
        overAll = (overAll * (P[i] % MOD)) % MOD;;
        exp++;
      }
      sol.push_back({P[i] % MOD, overAll, exp});
    }
  if (n != 1) {
    sol.push_back({n, n, 1});
  }

  return sol;
}

solution computeSol(vector<primeFactorInfo>& divs) {
  if (divs.size() == 0) {
    return {1, 1};
  }
  int res = 1;
  ll noDivs = 1;
  for (auto& div: divs) {
    ll denom = (div.overAll * div.p) % MOD - 1;
    if (denom < 0) denom += MOD;
    ll nom = div.p - 1;
    if (nom < 0) nom += MOD;

    res = (res * (denom * invMod[nom]) % MOD) % MOD;
    noDivs *= (div.exp + 1);
  }

  return {noDivs, res};
}

void solve() {
  scanf("%d", &tests);
  while (tests--) {
    scanf("%lld", &n);

    vector<primeFactorInfo> divs = decompose(n);
    solution sol = computeSol(divs);
    printf("%lld %lld\n", sol.noDivs, sol.sumDivs);
  }
}

int main() {
  freopen("ssnd.in", "r", stdin);
  freopen("ssnd.out", "w", stdout);

  prepare();
  solve();
  return 0;
}