E. Congruence Equation
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\n",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);
}
}
油!油!you@