x
2
=
k
n
+
1
x^2=kn+1
x2=kn+1
移项发现是个平方差
即
(
x
+
1
)
(
x
−
1
)
=
k
n
(x+1)(x-1)=kn
(x+1)(x−1)=kn
考 虑 拆 解
k
,
n
k,n
k,n
①
(
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
,
n
1
∗
n
2
=
n
k_1*k_2=k,n_1*n_2=n
k1∗k2=k,n1∗n2=n
发现可以枚举
n
n
n 的约数
y
y
y,
记作其中的
n
1
n_1
n1,
则有
n
2
=
n
/
y
n_2=n/y
n2=n/y,
(
x
+
1
)
=
k
1
∗
y
(x+1)=k1*y
(x+1)=k1∗y④
因为
x
<
n
x<n
x<n,
x
+
1
<
=
n
x+1<=n
x+1<=n,考虑枚举倍数
k
1
k_1
k1,
假设当前枚举倍数为
d
d
d
则有
(
x
+
1
)
=
d
∗
y
(x+1)=d*y
(x+1)=d∗y
即
x
=
d
∗
y
−
1
x=d*y-1
x=d∗y−1⑤
④⑤带入②,则有
(
d
∗
y
−
2
)
=
k
2
∗
(
n
/
y
)
(d*y-2)=k_2*(n/y)
(d∗y−2)=k2∗(n/y)
若
(
d
∗
y
−
2
)
(d*y-2)
(d∗y−2) 为
(
n
/
y
)
(n/y)
(n/y) 的倍数,则
x
=
d
∗
y
−
1
x=d*y-1
x=d∗y−1 为一组符合的解
同理可以将
y
y
y 记作其中的
n
2
n_2
n2,即由②推①
则有
(
d
∗
y
+
2
)
=
k
1
∗
(
n
/
y
)
(d*y+2)=k1*(n/y)
(d∗y+2)=k1∗(n/y)
若
(
d
∗
y
+
2
)
(d*y+2)
(d∗y+2) 为
(
n
/
y
)
(n/y)
(n/y) 的倍数,则
x
=
d
∗
y
+
1
x=d*y+1
x=d∗y+1 为一组可能的解,
因为这里是
(
x
−
1
)
−
>
(
x
+
1
)
(x-1)->(x+1)
(x−1)−>(x+1),
x
x
x 可能大于
n
n
n
p s : ps: ps:
- 一组约数
y
y
y ,
n
/
y
n/y
n/y,可能对应两个解
即 y − > x − 1 , ( n / y ) − > x + 1 y->x-1,(n/y)->x+1 y−>x−1,(n/y)−>x+1 或者 y − > x + 1 , ( n / y ) − > x − 1 y->x+1,(n/y)->x-1 y−>x+1,(n/y)−>x−1 - 枚举倍数时,选择大于
n
\sqrt{n}
n 的,
不然 ∑ ( k i ) \sum(k_i) ∑(ki) 可能和会很大
然后对于每个枚举的 约数,
可以 ( x − 1 ) − > ( x + 1 ) (x-1)->(x+1) (x−1)−>(x+1) 或者 ( x + 1 ) − > ( x − 1 ) (x+1)->(x-1) (x+1)−>(x−1)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
ll n, ans[N], num, cnt;
void Jud(ll y)
{
for (ll d = 0; d <= n / y; d++)
{
num = (d * y - 2);
if (!(num % (n / y))) ans[++cnt] = d * y - 1;
num = (d * y + 2);
if (!(num % (n / y))) ans[++cnt] = d * y + 1;
}
}
int main() {
scanf("%lld", &n);
if (n == 1) { printf("None\n"); return 0; }
ll siz = sqrt(n);
for(ll i = 1; i <= siz; i++) if (!(n % i)) Jud(n / i);
sort(ans + 1, ans + cnt + 1);
int m = unique(ans + 1, ans + cnt + 1) - ans - 1;
int l = 1, r = m;
while (ans[r] >= n) r--;
while (ans[l] < 0) l++;
if (!(r - l + 1)) printf("None");
else for(int i = l; i <= r; i++) printf("%lld\n", ans[i]);
}