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

CF 919E Congruence Equation 费马小+同余(循环节)

2018-02-03 22:25 246 查看
题意:给出a,b,p,x. p为素数.问有多少个1<=n<=x 满足n*a^n≡b(mod p)

1<=a,b<=p  1<=p<=1e6+3. 1<=x<=1e12.

因为p为素数 由费马小:a^(p-1)≡1 (mod p) a^p=a *a^(p-1) ≡ a (mod p) 得a^n %p 最小循环节为p-1.

n%p的最小循环节显然为p. 那么设n=i*(p-1)+j (0<=j<p) 

n*a^n≡ (i*(p-1)+j)%p * a^(i*(p-1)+j)%(p-1) ≡(j-i)*a^j ≡b (mod p)
因为1<=j<p 现在枚举j 得到 (j-i)≡b*a^-j(modp) 设右边的结果为y,则满足条件的i最小值为j-y.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,p,x;
ll qpow(ll x,ll n,ll mod)
{
ll s=1;
while(n)
{
if(n&1)
s=(s*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return s;
}
ll inv(ll x)
{
return qpow(x,p-2,p);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>a>>b>>p>>x;
ll res=0;
for(ll j=1;j<p;j++)
{
ll y=(b*inv(qpow(a,j,p)))%p;
ll first=((j-y+p)%p)*(p-1)+j;
if(first>x) continue;
res+=(x-first)/((p-1)*p)+1;
}
cout<<res<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: