您的位置:首页 > 产品设计 > UI/UE

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

2018-02-05 23:12 471 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: