版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/V5ZSQ/article/details/82917297
Description
在本题的题目描述中,托米是一个数学家,熟练掌握着任意进制的运算法则,托米喜欢一种数,比如 , 满足某种神秘性质,即 的任何一种循环位移都能由 表示,其中 , 为数字的长度
由于托米熟悉任意进制的运算法则,所以他会给你一个 和一个 , 你需要找出一个最大的 , ,满足 进制下存在一个长为 的正整数满足前文的神秘性质,例如 , 就是一个满足条件的,长度为 的二进制数
Input
一行输入
Output
输出题目要求的最大的 , 不存在输出
Sample Input
6 11
Sample Output
10
Solution
考虑长度为 的 进制数字 满足条件,那么 这个无限循环小数必然是有理数,也即存在 使得 ,由 所满足的条件知集合 和集合 的小数部分相同,而这等价于这两个集合中数字有理表示的分子模 的余数相同,即 和 在模 意义下相同,两边同乘 模 的逆元则有 和 相同,这意味着 是素数且 是模 逆元且,故只要从 到 从大到小枚举 判断 是否为 逆元即可
Code
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
bool check(int n)
{
for(int i=2;i*i<=n;i++)
if(n%i==0)return 0;
return 1;
}
int Pow(int a,int b,int c)
{
int ans=1;
while(b)
{
if(b&1)ans=(ll)ans*a%c;
a=(ll)a*a%c;
b>>=1;
}
return ans;
}
int n,x;
vector<int>v;
void deal(int n)
{
v.clear();
for(int i=2;i*i<=n;i++)
if(n%i==0)
{
v.push_back(i);
while(n%i==0)n/=i;
}
if(n>1)v.push_back(n);
}
bool Solve(int x)
{
for(int i=0;i<v.size();i++)
if(Pow(x,n/v[i],n+1)==1)return 0;
return 1;
}
int main()
{
scanf("%d%d",&n,&x);
if(x==2||!check(n+1))printf("-1\n");
else
{
deal(n);
int ans=-1;
for(int i=x-1;i>=2;i--)
if(Solve(i))
{
ans=i;
break;
}
printf("%d\n",ans);
}
}