题目描述
给出n,求所有x,使得x小于n,且
x
2
%
n
=
1
x ^ 2\ \%\ n\ =\ 1
x2 % n = 1
将所有x从小到大输出
思路
x
2
%
n
=
1
x ^ 2\ \%\ n\ =\ 1
x2 % n = 1
(
x
2
−
1
)
%
n
=
0
(x^2\ -\ 1)\ \%\ n\ =\ 0
(x2 − 1) % n = 0
x
2
−
1
=
k
n
x^2\ -\ 1 = kn
x2 − 1=kn
(
x
−
1
)
(
x
+
1
)
=
k
n
(x\ -\ 1)(x\ +\ 1)\ =\ kn
(x − 1)(x + 1) = kn
然后设
(
x
+
1
)
=
k
1
∗
n
1
(x\ +\ 1)\ =\ k_1 * n_1
(x + 1) = k1∗n1
(
x
−
1
)
=
k
2
∗
n
2
(x\ -\ 1)\ =\ k_2 * n_2
(x − 1) = k2∗n2
k
1
∗
k
2
=
k
k_1 * k_2 = k
k1∗k2=k
n
1
∗
n
2
=
n
n_1 * n_2 = n
n1∗n2=n
我们枚举
n
1
n_1
n1并记为
a
a
a
那么
n
2
=
n
/
a
n_2\ =\ n\ /\ a
n2 = n / a
(
x
+
1
)
=
k
1
∗
a
(x\ +\ 1)\ =\ k_1\ *\ a
(x + 1) = k1 ∗ a
我们再枚举
k
1
k_1
k1,记作
b
b
b
则
(
x
+
1
)
=
a
∗
b
(x\ +\ 1)\ =\ a\ *\ b
(x + 1) = a ∗ b
即
x
=
a
∗
b
−
1
x\ =\ a\ *\ b\ -\ 1
x = a ∗ b − 1
将此式代入
(
x
−
1
)
=
k
2
∗
n
2
(x\ -\ 1)\ =\ k_2 * n_2
(x − 1) = k2∗n2
得
(
a
∗
b
−
1
)
=
k
2
∗
(
n
/
a
)
(a\ *\ b\ -\ 1)\ =\ k_2\ *\ (n\ /\ a)
(a ∗ b − 1) = k2 ∗ (n / a)
若
(
a
∗
b
−
2
)
(a\ *\ b\ -\ 2)
(a ∗ b − 2)为
(
n
/
a
)
(n\ /\ a)
(n / a)的倍数
则
x
=
a
∗
b
−
1
x\ =\ a\ *\ b\ -\ 1
x = a ∗ b − 1为一组解
其余参考大爷博客
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
ll Ans[5000250];
ll n, m, t;
void init(ll n1)
{
for(ll k1 = 0; k1 <= n / n1; ++k1)
{
m = n1 * k1 - 2;//处理(x-1)和(x+1)
if(m % (n / n1) == 0)Ans[++t] = n1 * k1 - 1;
m = n1 * k1 + 2;
if(m % (n / n1) == 0)Ans[++t] = n1 * k1 + 1;
}
}
int main()
{
scanf("%lld", &n);
if(n == 1){printf("None\n"); return 0;}
for(int i = 1; i <= (ll)sqrt(n); ++i)
if(!(n % i))init(n / i);
sort(Ans + 1, Ans + t + 1);
t = 0;
while(Ans[++t] <= 0);t--;
while(Ans[++t] && Ans[t] <= n)if(Ans[t] != Ans[t - 1])printf("%lld\n", Ans[t]);
return 0;
}