Cod sursa(job #1973089)

Utilizator sabinandreiBocan Sabin Andrei sabinandrei Data 24 aprilie 2017 13:44:15
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 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 == 0)
    return 1;
  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;
}