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);
    }
}
posted @ 2018-02-01 20:15  sCjTyC  阅读(224)  评论(0编辑  收藏  举报