E. Congruence Equation
思路:
中国剩余定理
(a^n(modp) = a^{nmod(p-1)}(modp)),那么枚举在([0,n-2])枚举指数
求(a^i)关于p的逆元(ni)得原式为(k = ni*b(modp)),那么可以得到两个式子
(1.ni*b = n(modp))
(2.i = n(mod(p-1)))
然后通过中国剩余定理求出最小非负整数解t,那么通解(t + s*(p*(p-1)))
用除法在x范围内求下个数即可。复杂度(log(n)).
题链
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL quick(LL n,LL m,LL mod);
pair<LL,LL>ex_gcd(LL n,LL m);
int main(void)
{
LL a,b,p,x;
scanf("%lld %lld %lld %lld",&a,&b,&p,&x);
LL mod = p*(p-1);
LL sum = 0;
LL ask = 0;
for(LL i = 0;i < p-1;i++)
{
LL a_i = quick(a,i,p);
LL a_ni = quick(a_i,p-2,p);
LL a_b = b*a_ni%p;
sum = (a_b*(p-1)*(p-1)%mod + i*p*p%mod)%mod;
//cout<<sum<<endl;
if(x >= sum)
{
ask+=1;
ask += (x - sum)/mod;
}
}
printf("%lld
",ask);
return 0;
}
LL quick(LL n,LL m,LL mod)
{
n%=mod;
LL ask = 1;
while(m)
{
if(m&1)
ask = ask*n%mod;
n = n*n%mod;
m/=2;
}
return ask;
}
pair<LL,LL>ex_gcd(LL n,LL m)
{
if(m == 0)
return make_pair(1,0);
else
{
pair<LL,LL>ans = ex_gcd(m,n%m);
return make_pair(ans.second,ans.first - n/m*ans.second);
}
}