费马小定理&欧拉定理
费马小定理:
如果(p)是一个质数,而整数(a)不是(p)的倍数,(a^{p-1}equiv1pmod p)
欧拉定理:
当(a)与(n)互质时,(a^b equiv a^{b\%phi(n)} pmod n)
扩展欧拉定理:
[a^b equiv
egin{cases}
a^bpmod n (b<phi(n))\
a^{b\%phi(n)+phi(n)pmod n (bgephi(n))}\
end{cases}
]
BSGS
求方程(a^xequiv bpmod p)((a)与(p)互质)的解
取(m=lceil sqrt p
ceil),设(x = m*i-j)
那么易知,((a^m)^iequiv b*a^jpmod p)
我们可以把右边的全部丢到(map)里,然后枚举左边的,看看(map)中有没有
map<int, int> M;
int BSGS(int a, int b, int p) {
if (b == 1 && a) return 0;
M.clear(); int m = ceil(sqrt(p));
LL t = 1;
for (int i = 0; i < m; i++, t = t * a % p) M[t * b % p] = i;
for (int i = 1, s = t; i <= m + 1; i++, s = t * s % p) {
map<int, int> :: iterator it = M.find(s);
if (it == M.end()) continue;
return m * i - (it->second);
}
return -1;
}
int main() {
int a, b, p;
while (scanf("%d%d%d", &p, &a, &b) != EOF) {
int ans = BSGS(a, b, p);
if (ans == -1) puts("no solution");
else printf("%d
", ans);
}
return 0;
}
EXBSGS
当(a)与(p)不互质时,就不能除过去。
考虑,(a^x=p*z+b)
我们取(d = gcd(a,p))
如果(b)不是(d)的倍数显然无解
然后整体除(d)得到(frac{a}{d}a^{x-1}=frac{p}{d}*z+frac{b}{d})
显然可以递归处理。。
记录一下系数
然后最后回带一下即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Mod = 1e5 + 7;
int gcd(int x, int y) {
return !y ? x : gcd(y, x % y);
}
struct Hash {
struct node {
int a, b, nxt;
} A[1000010];
int lst[Mod], tot;
void clear() { memset(lst, 0, sizeof(lst)); tot = 0; }
void add(int a, int b, int S) {
A[++tot] = (node) {a, b, lst[S]};
lst[S] = tot;
}
void insert(int a, int b) { add(a, b, a % Mod); }
int find(int x) {
for (int i = lst[x % Mod]; i; i = A[i].nxt)
if (A[i].a == x) return A[i].b;
return -1;
}
} M;
int exBSGS(int a, int b, int p) {
if (b == 1 && a) return 0;
int d, k = 0, s = 1;
while ((d = gcd(a, p)) > 1) {
if (b % d) { return -1; }
b /= d; p /= d; k++; s = 1ll * s * a / d % p;
if (s == b) { return k; }
}
M.clear(); int m = ceil(sqrt(p));
LL t = 1;
for (int i = 0; i < m; i++, t = t * a % p) M.insert(t * b % p, i);
s = t * s % p;
for (int i = 1; i <= m + 1; i++, s = t * s % p) {
int it = M.find(s); if (it == -1) continue;
return m * i - it + k;
}
return -1;
}
int main() {
int a, b, p;
while (scanf("%d%d%d", &a, &p, &b) != EOF) {
if (!a && !b && !p) return 0;
int ans = exBSGS(a, b, p);
if (ans == -1) puts("No Solution");
else printf("%d
", ans);
}
return 0;
}