CodeForces - 919E Congruence Equation//同余式推理

题目:
在这里插入图片描述
思路:
n ∗ a n = b   ( m o d   p ) n*a^n=b\ (mod\ p) nan=b (mod p)
n = i + ( p − 1 ) ∗ k   ( m o d   p ) n=i+(p-1)*k\ (mod\ p) n=i+(p1)k (mod p)
得到 k = ( b / a i − i ) / ( p − 1 )   ( m o d   p ) / / k=(b/a^i-i)/(p-1)\ (mod\ p) // k=(b/aii)/(p1) (mod p)//费马小定理
然后枚举 i ∈ [ 0 , p − 2 ] i∈[0,p-2] i[0,p2],对于每一个 i i i 可以得到最小的正整数 k k k 满足同余式,那么 k + p ∗ j k+p*j k+pj 都是满足同余的,此时只需要保证 i + ( p − 1 ) ∗ ( k + p ∗ j ) < = x i+(p-1)*(k+p*j)<=x i+(p1)(k+pj)<=x n < = x n<=x n<=x 即可完美的不重不漏统计答案。
同余还是秒啊啊

/*   Author : Rshs   */
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define LDB long double
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
const LDB pai = acos(-1.0L);
const LDB eps = 1e-10;
const LL mod = 1e9+7;
const int MXN = 1e6+5;
LL infa[MXN],inv[MXN],fac[MXN];
void CCinit(int n,LL p){
    fac[0]=1;
    infa[1]=inv[1]=fac[1]=1;
    for(LL i=2;i<=n;i++) fac[i]=fac[i-1]*i%p; //阶乘
    for(LL i=2;i<=n;i++) inv[i]=(p-p/i)*inv[p%i]%p; //逆元
    for(LL i=2;i<=n;i++) infa[i]=infa[i-1]*inv[i]%p; //逆元前缀乘
}

int main(){
    LL a,b,p,x;cin>>a>>b>>p>>x;
    CCinit(1e6+5,p);
    LL ans=0;
    LL ai=1;
    for(LL i=0;i<p-1;i++,ai=ai*a%p){
        LL k=(b*inv[ai]%p-i)*inv[p-1]%p;
        k=(k+p)%p; //最小的k,之后k不停+p,要保证n=+k*(p-1)<=x
        LL yu=x-k*(p-1)-i;
        if(yu<0)continue;
        ans++;
        ans+=(yu/(p*(p-1)));

    }
    cout<<ans<<'\n';
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值