Cod sursa(job #1972311)

Utilizator GoogalAbabei Daniel Googal Data 22 aprilie 2017 19:39:11
Problema Suma divizorilor Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <fstream>
#include <iostream>

using namespace std;

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

int const modulo = 9901;

int a, b;

//recursiv
int effpower(int x, int y) {
  if(x == 0)
    return 0;
  else if(y == 1)
    return x;
  else{
    int result = effpower(x, (y >> 1));
    if((y & 1) == 0)
      return (result * result) % modulo;
    else
      return (((result * result) % modulo) * x) % modulo;
  }
}

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

int turn_to_inv(int x){
  long long inv = 0, ins;
  inv_mod(inv, ins, x, modulo);
  inv %= modulo;
  if(inv <= 0)
    inv = modulo + inv % modulo;
  return ((int) inv);
}

//S.D. = p^(e+1)-1 /(p -1)
int decompose(int a) {
  int exp = 0, sumadiv = 1;
  if(a%2 == 0) {
    while(a%2 == 0) {
      a /= 2;
      exp++;
    }
    exp *= b;
    //cout << exp;
    int factor = effpower(2, exp + 1) - 1;
    if(factor < 0)
      factor = modulo + factor % modulo;

    sumadiv = (sumadiv * factor) % modulo;
  }

  int i = 3;
  while(i * i <= a){
    exp = 0;
    while(a%i == 0){
      a /= i;
      exp++;
    }
    if(0 < exp) {
      exp = exp * b;
      if((i-1) % modulo == 0) {
        //i = k * modulo + 1
        //S.D. = i^(e+1)-1 /(i -1) == 1 + i + i^2 + .. i^e
        sumadiv = (sumadiv * (exp+1)) % modulo;
      } else {
        int factor = effpower(i % modulo, exp + 1) - 1;
        if(factor < 0)
            factor = modulo + factor % modulo;

         sumadiv = (sumadiv * factor) % modulo;
        //sumadiv /= (i - 1); //nu exista aceasta operatie in aritmetica modular
        sumadiv = (sumadiv * turn_to_inv(i - 1)) % modulo;
        //i-1 sigur nu mai e numar prim, deci e destuld e probabil ca (i-1) % modulo==0
      }
    }
    i += 2;
  }

  if(1 < a) {
    if((a - 1) % modulo == 0){
      sumadiv = (sumadiv * (b + 1)) % modulo;
    } else{
      int factor = effpower(a, b + 1) - 1;
      if(factor < 0)
        factor = modulo + factor % modulo;
      sumadiv = (sumadiv * factor) % modulo;
      sumadiv = (sumadiv * turn_to_inv(a - 1)) % modulo;
    }
  }
  return sumadiv;
}

int main() {
  in >> a >> b;
  out<<decompose(a);
  return 0;
}