Cod sursa(job #1247068)

Utilizator mgntMarius B mgnt Data 22 octombrie 2014 00:48:55
Problema Suma divizorilor Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.5 kb
#include <fstream>
#include <iostream>

int
dec
( int  m
, int  x
)
{ // Compute x-1 modulo m.
  x += (m-1);
  x %= m;
  return x;
}

int
exp
( int  m
, int  x
, int  k
)
{ // Compute x**k, modulo m.
  x %= m;
  int  e = 1;
  int  b = 1;
  while(0<k)
  { if(0 != (k & b) )
    { k ^= b;
      e *= x;
      e %= m;
    }
    x *= x;
    x %= m;
    b *= 2;
  }
  return e;
}

int
div
( int  p
, int  a
, int  b
)
{ // Compute a·b⁻¹ modulo p.
  // p is a prime number.
  int  x;
  int  y;
  x  = a % p;
  y  = exp(p, b, p-2);
  x *= y;
  x %= p;
  return x;
}

int
sumdiv
( int  A
, int  B
)
{ int  const m = 9901; // is a prime number.
  
  if(0 == (A%m)  )
  { return 0;
  }
  
  // f(x) = ∑ d ∣ x 😼 d.
  // f is multiplicative.
  int  f = 1;
  int  p;
  for(p=2; 1<A; ++p)
  { if(0 == (A%p) )
    { int  k = 0;
      while(0 == (A%p) )
      { A /= p;
        ++k;
      }
      k *= B;
      ++k;
      
      // Sum of divisors of pᵐ is
      // ∑ k←0..m 😼 pᵏ = (pᵐ⁺¹ - 1)/(p-1).
       
      int  a = dec(m, exp(m, p, k));
      int  b = dec(m, p);
      int  c = div(m, a, b);
      f *= c;
      f %= m;
    }
  }
  return f;
}

bool
solve
()
{ ::std::ifstream  is("sumdiv.in");
  
  int  A;
  int  B;
  is >> A >> B;
  
  int  const C = sumdiv(A, B);
  
  ::std::ofstream  os("sumdiv.out");
  os << C << ::std::endl;
  
  return true; // Success.
}

int
main
()
{ int  status;
  try
  { bool  const ok = solve();
    status = ( ok ? 0 : 1 );
  }
  catch ( ... )
  { status = 2;
  }
  return status;
}