/*
题意:n*a^n≡b(mod p),其中1<=n<=x,求满足条件的n的个数
思路:令n=i×(p−1)+j,因为根据费马小定理可以保证j有解,所以有
n*a^(i*(p-1)+j)≡b(mod p)
n≡b*a^-1(mod p)
i×(p−1)+j≡b*a^-1(mod p)
j-i≡b*a^-1(mod p)
我们枚举j,此时j介于1与p-1之间,令c=b*a^-1(mod p),
求出i,之后求出最小的n满足条件,注意到循环节为p*(p-1)
所以n+k*p(p-1)就是此时j固定的解,用x去除便可得出数量
(此时加上循环节不会影响答案,只是为了充分利用x的大小而已)
特判n=0,此时不满足题意,我们只去考虑循环节就行
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
ll qpow(ll a, ll b, ll p)
{
ll ans = 1;
while (b)
{
if (b & 1)
ans = ans*a%p;
a = a*a%p;
b /= 2;
}
return ans;
}
int main()
{
ll a, b, x, p;
scanf("%lld%lld%lld%lld", &a, &b, &p, &x);
ll ans = 0, repetend = p*(p - 1);
for (ll j = 1; j <= p - 1; j++)
{
ll c = b*qpow(qpow(a, j, p), p - 2, p) % p;//b*逆元
ll i = (j - c + p) % p;
ll n = (i*(p - 1) + j) % repetend;
if (n == 0)//特判n>0
n = repetend;
ans += x / repetend + (x%repetend >= n);
}
printf("%lld\n", ans);
return 0;
}
codeforces 919E. Congruence Equation
猜你喜欢
转载自blog.csdn.net/Egqawkq/article/details/79312584
今日推荐
周排行