进阶篇
问题:
x a ≡ b ( m o d p ) x^a\equiv b(mod~p)\\ xa≡b(mod p)
解法一:
设
g
g
g是p的一个原根,根据原根的性质存在
c
c
c,满足
g
c
≡
x
g^c\equiv x
gc≡x成立,同理存在
t
t
t,满足
g
t
≡
b
g^t\equiv b
gt≡b成立。
∴
(
g
c
)
a
≡
b
(
m
o
d
p
)
(
g
a
)
c
≡
b
(
m
o
d
p
)
g
a
已
知
,
所
以
我
们
就
能
用
基
础
篇
直
接
求
解
c
,
也
就
是
一
个
特
解
。
\therefore (g^c)^a\equiv b(mod~p)\\ (g^a)^c\equiv b(mod~p)\\ g^a已知,所以我们就能用基础篇直接求解c,也就是一个特解。
∴(gc)a≡b(mod p)(ga)c≡b(mod p)ga已知,所以我们就能用基础篇直接求解c,也就是一个特解。
解法二:
设
g
g
g是p的一个原根,根据原根的性质存在
c
c
c,满足
g
c
≡
x
g^c\equiv x
gc≡x成立,同理存在
t
t
t,满足
g
t
≡
b
g^t\equiv b
gt≡b成立。
∴
g
a
c
≡
g
t
(
m
o
d
p
)
根
据
阶
的
性
质
有
∴
a
c
≡
t
(
m
o
d
φ
(
p
)
)
根
据
e
x
g
c
d
求
出
c
,
也
是
一
个
特
解
。
\therefore g^{ac}\equiv g^t(mod~p)\\ 根据阶的性质有\\ \therefore ac\equiv t(mod~\varphi(p))\\ 根据exgcd求出c,也是一个特解。
∴gac≡gt(mod p)根据阶的性质有∴ac≡t(mod φ(p))根据exgcd求出c,也是一个特解。
求全部的解:
我们在已知一个特解
g
c
g^c
gc的情况下,我们要得到全部解。
∵
g
φ
(
p
)
≡
1
(
m
o
d
p
)
∴
∀
t
∈
Z
,
x
a
≡
g
c
a
+
t
φ
(
p
)
a
(
m
o
d
p
)
∴
∀
t
∈
Z
且
a
∣
t
φ
(
p
)
,
x
≡
g
c
+
t
φ
(
p
)
a
(
m
o
d
p
)
∵
a
∣
t
φ
(
p
)
∴
a
g
c
d
(
a
,
φ
(
p
)
)
∣
t
∴
t
=
a
g
c
d
(
a
,
φ
(
p
)
)
i
∴
全
部
的
解
为
:
∀
i
∈
Z
,
x
≡
g
c
+
φ
(
p
)
g
c
d
(
a
,
φ
(
p
)
)
i
(
m
o
d
p
)
(
解
的
个
数
为
g
c
d
(
a
,
φ
(
p
)
)
)
\because g^{\varphi(p)}\equiv1(mod~p)\\ \therefore\forall t\in\mathbb{Z}, x^a\equiv g^{ca+\frac {t\varphi(p)}a}(mod~p)\\ \therefore\forall t\in\mathbb{Z}且a|t\varphi(p),x\equiv g^{c+\frac{t\varphi(p)}{a}}(mod~p)\\ \because a|t\varphi(p)\\ \therefore \frac a{gcd(a, \varphi(p))}|t\\ \therefore t =\frac a{gcd(a, \varphi(p))}i\\ \therefore 全部的解为:\forall i\in\mathbb{Z},x\equiv g^{c+\frac {\varphi(p)}{gcd(a,\varphi(p))}i}(mod~p)\\ (解的个数为gcd(a,\varphi(p)))\\
∵gφ(p)≡1(mod p)∴∀t∈Z,xa≡gca+atφ(p)(mod p)∴∀t∈Z且a∣tφ(p),x≡gc+atφ(p)(mod p)∵a∣tφ(p)∴gcd(a,φ(p))a∣t∴t=gcd(a,φ(p))ai∴全部的解为:∀i∈Z,x≡gc+gcd(a,φ(p))φ(p)i(mod p)(解的个数为gcd(a,φ(p)))
题目:
P3306 [SDOI2013] 随机数生成器
根据题意将原式化成等比数列的形式。再去推式子。
x i + 1 ≡ a x i + b ( m o d p ) x i + 1 + b a − 1 ≡ a ( x i + b a − 1 ) ( m o d p ) x n ≡ t ( m o d p ) a n − 1 ( x 1 + b a − 1 ) − b a − 1 ≡ t ( m o d p ) a n − 1 ≡ ( t + b a − 1 ) ∗ i n v ( x 1 + b a − 1 ) ( m o d p ) x_{i+1}\equiv ax_i+b(mod~p)\\ x_{i+1}+\frac b{a-1}\equiv a(x_i+\frac b{a-1})(mod~p)\\ x_n\equiv t(mod~p)\\ a^{n-1}(x_1+\frac b{a-1})-\frac b{a-1}\equiv t(mod~p)\\ a^{n-1}\equiv (t + \frac b{a-1})*inv(x_1+\frac b{a-1})(mod~p)\\ xi+1≡axi+b(mod p)xi+1+a−1b≡a(xi+a−1b)(mod p)xn≡t(mod p)an−1(x1+a−1b)−a−1b≡t(mod p)an−1≡(t+a−1b)∗inv(x1+a−1b)(mod p)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll qpow(ll x, ll y, ll mod) {
ll ans = 1;
while(y) {
if(y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
unordered_map<ll, ll> mp;
ll bsgs(ll a, ll b, ll p) {
if(a % p == 0) return -1;
mp.clear();
ll k = ceil(sqrt(p));
for(int i=0; i<=k; i++) {
mp[b] = i;
b = b * a % p;
}
ll aa = qpow(a, k, p), A = aa;
for(int i=1; i<=k; i++) {
if(mp[aa]) {
return 1ll * i * k - mp[aa] + 1;
}
aa = aa * A % p;
}
return -1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
cin >> t;
while(t--) {
ll p, a, b, x, t;
cin >> p >> a >> b >> x >> t;
if(x == t) {
cout << 1 << endl;
continue;
}
if(a == 0) {
if(b == t) cout << 2 << endl;
else cout << -1 << endl;
continue;
}
if(a == 1) {
if(b == 0) cout << -1 << endl;
else {
ll k = qpow(b, p-2, p);
cout << ((t-x+p)%p*k) % p + 1 << endl;
}
continue;
}
ll tmp = b*qpow(a-1, p-2, p) % p;
t = (t + tmp) % p;
t = t * qpow((x+tmp)%p, p-2, p) % p;
ll ans = bsgs(a, t, p);
cout << ans << endl;
}
return 0;
}
261. Discrete Roots模板
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll qpow(ll x, ll y, ll mod) {
ll ans = 1;
while(y) {
if(y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
ll G(ll p) {//求原根
if(p == 2) return 1;
vector<ll> tmp;
int phi = p-1, n = phi;
for(int i=2; 1ll*i*i<=n; i++) {
if(n % i == 0) {
tmp.push_back(i);
while(n % i == 0) n /= i;
}
}
if(n > 1) tmp.push_back(n);
for(int i=1; i<=p; i++) {
bool flag = 0;
for(auto it : tmp) {
if(qpow(i, phi/it, p) == 1) {
flag = 1;
break;
}
}
if(!flag) return i;
}
return -1;
}
unordered_map<ll, ll> mp;
ll bsgs(ll a, ll b, ll p) {
if(a % p == 0 && b != 0) return -1;
mp.clear();
int k = ceil(sqrt(p));
for(int i=0; i<=k; i++) {
mp[b] = i;
b = b * a % p;
}
ll aa = qpow(a, k, p), A = aa;
for(int i=1; i<=k; i++) {
if(mp[A]) return 1ll * i * k - mp[A];
A = A * aa % p;
}
return -1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
ll p, k, a;
while(cin >> p >> k >> a) {
if(a == 0) {
cout << "1\n0\n";
continue;
}
ll g = G(p), gk = qpow(g, k, p);
ll x0 = bsgs(gk, a, p), t = bsgs(g, a, p);
if(x0 == -1) {
cout << "0\n";
continue;
}
vector<ll> ans;
ll d = __gcd(p-1, k), mod = (p-1)/d;
x0 = x0 % mod;
for(int i=0; i<d; i++) {//最多只有d个不同的解。
ans.push_back(qpow(g, ( x0+i*mod%(p-1) )%(p-1), p));
}
sort(ans.begin(), ans.end());
cout << ans.size() << endl;
for(auto it : ans) cout << it << ' ';
cout << endl;
}
return 0;
}