题目及代码:题目大意就是 给定一个数n,找出所有的m(m>=1&&m<=n)使得gcd(m,n)=n^m。
本来觉得这个n一定是要进行素因子分解的,之后利用因子枚举n所有的约数,然后思路就断了。索性看了看官方的题解,的确是要枚举n所有的因子,不过不需要素因子分解,直接暴力就可以了。然后我们假设gcd(n,m)=k,这里k是n的一个因子,那么我们就可以得出n^m=k,这里两边同时亦或n,得到n^n^m=n^k,即m=n^k,那么我们可以通过枚举n的因子k以得到待定的m,然后在根据gcd(m,n)是否等于k来判断m是否符合要求,具体见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b)
{
LL r=a%b;
while(r)
{
a=b;
b=r;
r=a%b;
}
return b;
}
LL nt[220];
int main()
{
int cas=1;
LL n,m;
while(scanf("%I64d",&n)!=EOF)
{
int k=0;
for(LL i=1;i*i<=n;i++)
if(n%i==0)
{
m=(n^i);
if(m>=1&&m<=n&&gcd(n,m)==i)
{
nt[k++]=m;
}
if(i*i!=n)
{
m=n^(n/i);
if(m>=1&&m<=n&&gcd(n,m)==n/i)
{
nt[k++]=m;
}
}
}
sort(nt,nt+k);
printf("Case #%d:\n",cas++);
printf("%d\n",k);
if(k>0)
{
printf("%I64d",nt[0]);
for(int i=1;i<k;i++)
{
printf(" %I64d",nt[i]);
}
}
puts("");
}
return 0;
}