4861 按钮
给定一个m进制的数1,每次乘以一个k,问最少几次之后,这个数的末尾会有1
标签上竟然有暴力枚举
不是吧阿Sire
不过这个题可能得用一种类似于枚举的方法叫做BSGS做法
可惜我不会
我先用同余来做吧
这里还涉及到了关于hash的一个小常识,如果这个进制m和乘积k是互质的才有可能,不互质是永远不可能乘到1的
在这个题里,和枚举差不多,难理解,在纸上算算
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int m,k;
int ans,ans1;
long long x,y;
int ty(int x,int y)//x^y
{
int ans=1;
for (;y;y>>=1,x=(long long)x*x%m)
if(y&1)
ans=(long long)ans*x%m;
return ans;
}
int gcd(int a,int b) {
if(a<b)
swap(a,b);
return b==0?a:gcd(b,a%b);
}
int zc(int n)
{
int ret=n;
for(int i=2;i*i<=n;i++)
if (n%i==0)
{
ret=ret/i*(i-1);
do n/=i;
while(n%i==0);
}
if (n>1)
ret=ret/n*(n-1);
return ret;
}
int main ()
{
cin>>m>>k;
if(gcd(m,k)!=1)//m和k不互质,则永远不可能
{
printf("Let's go Blue Jays!\n");
return 0;
}
else
{
ans=ans1=zc(m);
for(int i=2; i*i<=ans1; i++)
if(ans1%i==0)
{
if(ty(k,i)==1)
ans=min(ans,i);//找到答案
if(ty(k,ans1/i)==1)//算最小的答案
ans=min(ans,ans1/i);
}
printf("%d\n",ans);
}
return 0;
}
BSGS
听说这个做法才是正解
BSGS是用来解决xy同余的问题,又叫北上广深拔山盖世的算法,不过因为这个算法是NOI级别的
所以不想学了