【CodeForces - 919E】 Congruence Equation 【费马小定理 + 思维】

Given an integer x. Your task is to find out how many positive integers n (1 ≤ n ≤ x) satisfy

这里写图片描述

where a, b, p are all known constants.
Input
The only line contains four integers a, b, p, x (2 ≤ p ≤ 106 + 3, 1 ≤ a, b < p, 1 ≤ x ≤ 1012). It is guaranteed that p is a prime.

Output
Print a single integer: the number of possible answers n.

Example
Input
2 3 5 8
Output
2
Input
4 6 7 13
Output
1
Input
233 233 10007 1
Output
1
Note
In the first sample, we can see that n = 2 and n = 8 are possible answers

分析:
看式子 我们可以知道 其一个循环周期为 p * (p-1) (注意这个周期可不是最小正周期),但是因为 循环节太大了,所以我们只能够换个思路 。
因为看着像BSGS题目,所以借用其思路 。但是 n 和 a^n的循环节不同,所以我们可供选择的方向有两个 。
1) 因为n的循环节为p,我们可以令 n = i * p + j ,带入式子中,化简后可得到 j*a^j=b*a^(-i) (mod p) 其实这里就是和bsgs的情况一样,一样的方法确实可以得到其最小解,但是这个题目求的是其解的个数,主要就是我们无法知道其最小正周期为多少,所以我们光求出它的最小解是没有用的。
2 )因为a^n的循环节为phi(p), 所以我们可以令n=i*(p-1)+j ,代入式子中可得到 i = j - b*a^(-j) (mod p) ,数据的范围 0< n <=x ==》 i*(p-1)+j<=x ==》 i < (x-j) / (p-1) ,0<= j < p-1 . 然后我们可以枚举 j , 得到 可以使n为正解的最小的 i ,然后i的上界我们也有,为(x-j)/(p-1) ,并且其通解为 i + k * p ,这样就可以得到其解的个数 。

i = j - b*a^(-j) (mod p) 关键枚举的式子。
转化一点 ,i = j - b*(a^-1)^j (mod p )

#include<bits/stdc++.h>
using namespace std;
#define LL long long

const int N = 100000+3;
const int MAXM = 1e6;
const int mod = 7653;
const int inf = 0x3f3f3f3f;

LL qpow(LL a,LL b,LL c ){
    LL s=1,base=a%c;
    while(b){
        if(b&1) s=s*base%c;
        base=base*base%c;
        b>>=1;
    }
    return s;
}

int main(){
    LL a,b,p,x;
    cin>>a>>b>>p>>x;
    LL inva=qpow(a,p-2,p);
    LL t=1;  LL ans=0;
    for(int j=0;j<p-1;j++){
        LL i=(j-b*t%p+p)%p; //得到最小正解 i 
        if(i==0&&j==0) i=p; // 这种情况下 n是为0 不是我们想要的。
        if(x>=j){
            LL up=(x-j)/(p-1);
            if(up-i>=0) ans+=(up-i)/p+1;
        }
        t=t*inva%p;
    }
    cout<<ans<<"\n";
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值