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
",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);
    }
}
原文地址:https://www.cnblogs.com/zzuli2sjy/p/8401082.html