Cod sursa(job #1247162)

Utilizator mgntMarius B mgnt Data 22 octombrie 2014 11:09:55
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 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
geometricProgression
( int  m
, int  p
, int  k
, int  B
)
{ p %= m;
  if(1 == p)
  { return ((1 + (k%m)*(B%m)) % m);
  }
  
  // Sum of divisors of pᵐ is
  // ∑ k←0..m 😼 pᵏ = (pᵐ⁺¹ - 1)/(p-1).
  int  a;
  a  = exp(m, p, k);
  a  = exp(m, a, B);
  a *= p;
  a %= m;
  a = dec(m, a);
  int  b = dec(m, p);
  int  c = div(m, a, b);
  return c;
}

int
sumdiv
( int  A
, int  B
)
{ if((0==A) && (0<B))
  { return 0;
  }
  
  if((0==A) && (0==B))
  { return 1;
  }
  
  int  const m = 9901; // is a prime number.
  
  // f(x) = ∑ d ∣ x 😼 d.
  // f is multiplicative.
  int  f = ((0<A) ? 1: 0);
  int  p;
  int  k;
  int  g;
  for(p=2; p*p <= A; ++p)
  { if(0 == (A%p) )
    { k = 0;
      while(0 == (A%p) )
      { A /= p;
        ++k;
      }
      
      g = geometricProgression(m, p, k, B);
      
      f *= g;
      f %= m;
    }
  }
  
  if(1<A)
  { p = A;
    k = 1;
    
    g = geometricProgression(m, p, 1, B);
    
    f *= g;
    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;
}