Бусинки n цветов соединены между собой в циклическое ожерелье из n бусинок (n ≤ 109). Вам следует подсчитать количество
различных ожерелий, которое можно получить. В ожерелье не обязательно
использовать все n цветов.
Повторениями, полученными в результате вращения ожерелья вокруг центра, следует
пренебречь.
Вывести ответ по модулю p.
Вход. Первая строка содержит количество тестов x (x
≤ 3500). Каждая из следующих x
строк содержит два числа n и p (1 ≤ n ≤ 109, 1 ≤ p ≤ 30000).
Выход. Для каждого теста вывести ответ
в отдельной строке.
Пример
входа |
Пример
выхода |
5 1 30000 2 30000 3 30000 4 30000 5 30000 |
1 3 11 70 629 |
теорема
Пойа
Анализ алгоритма
При подсчете
ожерелий следует пренебречь его вращениями, но не отображениями относительно
осей симметрии. Бусинки можно красить k
= n цветами. Количество различных
ожерелий равно (учитывая что n = k)
=
В случае
вычисления ответа по формуле
=
получим Time
Limit.
Пример
Пусть количество бусинок равно n = 4, количество цветов равно k = 4. Тогда количество ожерелий равно
= = = = 70
Реализация алгоритма
Функция euler(n) вычисляет функцию Эйлера φ(n).
int
euler(int n)
{
int i, result
= n;
for(i = 2; i
* i <= n; i++)
if (n % i
== 0)
{
result -= result / i;
while (n
% i == 0) n /= i;
}
if (n > 1)
result -= result / n;
return result;
}
Вычисление степени числа по модулю: xn mod p.
int power(int
x, int n)
{
int res =
1;
x = x % p;
while(n)
{
if (n & 1) res = (res * x) % p;
x = (x * x) %
p;
n >>= 1;
}
return res;
}
Основная часть программы. Читаем
входные данные.
scanf("%d",&tests);
while(tests--)
{
scanf("%d
%d",&n,&p);
k = n; res = 0;
Перебираем делители i числа n от 1 до . Если i – делитель
n, то n / i также будет
делителем n.
for(i = 1; i
* i < n; i++)
if
(n % i == 0)
{
res = (res + euler(i) % p *
power(k,n/i-1)) % p;
res = (res + euler(n/i) % p *
power(k,i-1)) % p;
}
Отдельно обработаем случай, если n является полным квадратом.
if (i * i == n)
res = (res + euler(i) * power(k,i-1)) % p;
Выводим ответ res.
printf("%d\n",res);
}