luogu P4861 【按钮】
首先根据题意可以看出题目要求的是
\[K^x \equiv 1 \ (mod\ M)
\]
\(x\)的最小正整数解。
如果$\ gcd(M,K)=1\ $则有解。
然后,根据欧拉定理,得到
\[K^{\phi(M)}\equiv 1 \ (mod\ M)
\]
但\(\phi(M)\)并不一定是\(x\)的最小整数解。
可以猜到\(x|\phi(M)\)。证明别的题解有讲,这里不多说。
所以可以枚举\(\phi(M)\)的约数,找到最小的\(x\)满足
\[K^x\equiv1\ (mod\ M)\ ,\ x|\phi(M)
\]
\(\phi(M)\)用这个式子算
\[M=\prod_{i=1}^{n} p_i^{c_i}
\]
\[\phi(M)=M \prod_{i=1}^{n}\frac{p_i-1}{p_i}
\]
就做完了。
\(Code:\)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define int long long
#define _min(a,b) ((a)<(b)?(a):(b))
inline int read(){
register int x=0,f=0,ch=getchar();
while('0'>ch||ch>'9')f^=ch=='-',ch=getchar();
while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
return f?-x:x;
}
int res,phi;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
inline void Gphi(int x){//找phi
phi=x;
for(register int i=2;i*i<=x;++i){
if(x%i==0){
phi=phi/i*(i-1);
while(x%i==0)x/=i;
}
}
if(x>1)phi=phi/x*(x-1);
}
inline int qpow(int x,int p,int P){//快速幂
res=1;
for(;p;p>>=1,x=x*x%P)if(p&1)res=res*x%P;
return res%P;
}
#define INF 0x3f3f3f3f3f3f3f3f
int m,k,ans=INF;
inline int Gans(int x){//枚举约数找答案
for(register int i=1;i*i<=x;++i){
if(x%i==0){
//这里显然 i<=x/i,因为我们枚举的i满足i<=sqrt(x)的,所以当i有解时,不用判断x/i的答案
if(qpow(k,i,m)%m==1)ans=_min(ans,i);
else if(qpow(k,x/i,m)%m==1)ans=_min(ans,x/i);
}
}
return ans;
}
signed main(){
m=read(),k=read();
if(gcd(m,k)==1){
Gphi(m);
printf("%lld\n",Gans(phi));
}else printf("Let's go Blue Jays!\n");
return 0;
}
笔者比较菜,有什么问题私信,谢谢