• Codeforces 919E


    919E - Congruence Equation

    思路:

    费马小定理。

    n*a^n = b (mod p)

    根据费马小定理 a^(p-1) = 1 (mod p)

    我们把n化为 n=i+y(p-1)

    于是[i+y(p-1)]*a^ [i+y(p-1)] = b (mod p)

    再根据费马小定理a^ [i+y(p-1)]=a^i  (mod p)

    于是[i+y(p-1)]*a^i = b (mod p)

    于是y = (b/(a^i)-i)/(p-1) (mod p)

    于是y = (b/(a^i)-i)/(p-1) +k*p(除法用逆元做)

    我们发现如果i>p,那么mod p 后还是在0 到 p-1的范围内,所以 0<=i<p,又因为i=0不满足题意,于是0<i<p

    于是题目就转换成了遍历i,对于每个i,找有多少个y满足题意

    因为n<=x,所以i+y*(p-1)<=x,所以y<=(x-i)/(p-1),所以对于每个i的y的上界可以确定,找y的个数就很简单了

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e6+5;
    int inv[N];
    void init(int p){
        inv[1]=1;
        for(int i=2;i<p;i++)inv[i]=(p-p/i)*1ll*inv[p%i]%p;
    }
    ll qpow(ll a,ll b,ll p){
        ll ans=1;
        while(b){
            if(b&1)ans=(ans*a)%p;
            b>>=1;
            a=(a*a)%p;
        }
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        ll a,b,p,x;
        cin>>a>>b>>p>>x;
        init(p);
        ll ans=0;
        for(int i=1;i<p;i++){
            ll t=qpow(a,i,p);
            ll y=((b*inv[t]-i+p)%p*inv[p-1])%p;
            ll yy=(x-i)/(p-1);
            if(i+y*(p-1)>x)continue;
            ll add=(yy-y)/p+1;
            ans+=add;
            //cout<<i<<' '<<add<<' '<<y<<' '<<yy<<endl;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    数组操作方法和迭代方法
    三元运算符
    数组求和/去重
    javascript保留字
    window.onload和document.ready区别
    alert()和consloe.log()区别
    Eventutil函数封装
    前端中的事件流
    react的生命周期
    小程序初体验
  • 原文地址:https://www.cnblogs.com/widsom/p/8399755.html
Copyright © 2020-2023  润新知