Codeforces - 919E - Congruence Equation
可以发现
P=p×(p−1)
是
n×an(mod p)
的循环节
但
p×(p−1)
太大,考虑到
ap−1≡1(mod p)
,令
n=i×(p−1)+j
:
n×an≡b(mod p)n×ai×(p−1)+j≡b(mod p)n=b×a−j(mod p)i×(p−1)+j=b×a−j(mod p)j−i=b×a−j(mod p)
。
根据 j 从
本题的关键在于找到循环节然后将 n <script type="math/tex" id="MathJax-Element-1253">n</script> 拆解至根号复杂度枚举求解。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll powm(ll a, ll b, ll p)
{
ll c = 1;
while(b)
{
if(b&1) c=c*a%p;
a=a*a%p;
b>>=1;
}
return c;
}
int main()
{
ll a,b,x,p;
scanf("%I64d%I64d%I64d%I64d",&a,&b,&p,&x);
ll ans = 0;
ll P = p*(p-1);
for(ll j=1;j<p;++j)
{
ll c = b*powm(powm(a,j,p),p-2,p)%p;
ll i = (j-c+p)%p;
ll n = (i*(p-1)+j)%P;
if(n==0) n=P;
ans+=x/P+(x%P>=n);
}
printf("%I64d\n",ans);
}