数论白痴上线。
参考了http://blog.csdn.net/baidu_36797646/article/details/79225155的博文。
思路:n%p的周期为p,a^n%p的周期为p-1,则(n*(a^n))%p的周期为p*(p-1),只要算一个周期里面满足的就好。但是这个周期太大,想到利用n%p和a^n%p的周期差,n每增加p-1,n%p减1,a^n%p不变,这样就可以对于枚举1~p-1的n,设m=n+k*(p-1),(1<=m<=P)一个周期内必有一个m满足同余方程。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll MOD;
ll a,b,p,x;
ll quick_pow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)ans=(ans*a)%MOD;
b>>=1;
a=(a*a)%MOD;
}
return ans;
}
int main()
{
while(~scanf("%I64d%I64d%I64d%I64d",&a,&b,&p,&x))
{
ll P=(p-1)*p;
MOD=p;
ll k;
ll ans=0;
for(ll n=1;n<p;n++)
{
if(n>x)break;
k=(b*(quick_pow(quick_pow(a,n),p-2)))%MOD;
ll c;
if(n>=k)
c=(n+(n-k)*(p-1))%P;
else
c=(n+(n+p-k)*(p-1))%P;
if(c==0)c=P;
ans+=(x/P)+(x%P>=c?1:0);
}
printf("%I64d\n",ans);
}
}