Помогите пожалуйста решить задачу когда a i m не взаимно просты.
Для взаимно простых есть статья http://e-maxx.ru/algo/discrete_log где сказаночто алгоритм можно модифицировать ... не придумал как :(((
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 161 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | awoo | 154 |
8 | Dominater069 | 154 |
10 | luogu_official | 150 |
Помогите пожалуйста решить задачу когда a i m не взаимно просты.
Для взаимно простых есть статья http://e-maxx.ru/algo/discrete_log где сказаночто алгоритм можно модифицировать ... не придумал как :(((
Название |
---|
и достаточно, чтобы b делилось на НОД(a,m), тогда можно m разделить на НОД, а b сделать таким, чтобы правильное решение подходило под новое уравнение.
upd.А дальше есть несколько пока не устраненных мной проблем.Ваш комент похоже единственный в рунете поясняет как доработать Шенкса для произвольных чисел (если правильно Вас понял: если b не делиться на gcd(a,m) то нет решений, иначе взять gcd(a,m) если он отличен от 1 делить m на него пока нет остатка, а потом взять b по модулю m. Решать с ними и как встретится решение для новых b и m, то проверить его для старых переменных? эта задача зашла этим способом). Не подскажите где Вы нашли это замечание или если не помните, то почему оно работает?
Если корень есть, то мы его таким образом обязательно найдем, т.к. если a = b(mod m), то и если m делится на k. Количество корней мы таким образом увеличим, так что нужно обязательно каждый корень проверить на то, подходит ли он под исходное уравнение.
Пусть надо найти дискретный логарифм b по основанию а по модулю m. (a^x = b (mod m)) Пусть p_1, p_2, p_3, ..., p_k — все общие простые делители у a и m. Пусть число n получается из числа m делением на все простые p_1 ... p_k в максимальной степени.
То есть m = n * (p_1 ^ M_1) * (p_2 ^ M_2) * ... * (p_k ^ M_k), где M_1 ... M_k — степени вхождения соответствующего простого в M. Аналогично определим A_1 ... A_k и B_1 ... B_k для чисел a и b соответственно.
1 случай) Для некоторого i от 1 до k B_i < M_i. Тогда, поскольку A_i >= 1, при x >= (B_i + 1) / A_i a^x кратно p_i ^ (B_i + 1), а b — нет. Значит, a^x != b (mod m) при x >= (B_i + 1) / A_i . Значит, достаточно перебрать все x < (B_i + 1) / A_i.
2 случай) Для всех i от 1 до k B_i >= M_i. Тогда решаем a^x = m (mod n) (Теперь a и модуль взаимно просты). Если нет решений, то нет и у исходной задачи. Если решение x нашлось, то прибавляем к х ф(n) (функция Эйлера), пока не станет x >= max(M_i / A_i). Тогда остаток a^x mod n не поменяется, а на все p_i ^ M_i начнёт делиться. Значит, будет a^x = b (mod m).
Асимптотика:
Вычисление n, p_i, A_i, B_i, M_i: O(sqrt(m)).
1 cлучай: O(log(m)).
2 случай: дискретное логарифмирование O(sqrt(n)log(n)) + прибавление ф(n) O(log(m)) = O(sqrt(m)log(m)).
Итого: O(sqrt(m)log(m)).
При этом в обоих случаях ответ x помещается в диапазон [0; m):
1 случай: x < B_i + 1 <= m (ведь m >= 2^B_i >= B_i + 1).
2 случай: x < max(M_i / A_i) + ф(m) <= max(M_i) + ф(n) <= [log2(m / n)] + ф(n) <= m — 1, поскольку если [log2(m / n)] = t, то m >= n * 2^t, тогда m — 1 >= n * 2^t — 1 >= n + 2^t — 2 = (2^t — 1) + (n — 1) >= t + ф(n) = [log2(m / n)] + ф(n).