题目大意:
N < = 1 0 14 N<=10^{14} N<=1014
分析:
这个可以推一下,
设
x
=
N
−
T
x=N-T
x=N−T,
可以推成
N
−
T
2
x
\frac{N-\frac{T}{2}}{x}
xN−2T
因为
T
=
N
−
x
T=N-x
T=N−x
所以可以写成
N
−
N
−
x
2
x
\frac{N-\frac{N-x}{2}}{x}
xN−2N−x
可以化成
N
−
N
2
+
x
2
x
\frac{N-\frac{N}{2}+\frac{x}{2}}{x}
xN−2N+2x
然后就是
N
2
+
x
2
x
\frac{\frac{N}{2}+\frac{x}{2}}{x}
x2N+2x
即
N
2
x
+
1
2
\frac{N}{2x}+\frac{1}{2}
2xN+21
那么这个东西我们设为
k
k
k
即
N
2
x
+
1
2
=
k
\frac{N}{2x}+\frac{1}{2}=k
2xN+21=k
那么同乘
2
2
2,
即
N
x
+
1
=
2
k
\frac{N}{x}+1=2k
xN+1=2k
那么我们就可以知道,当
x
x
x为
N
N
N的约数并且
N
x
+
1
\frac{N}{x}+1
xN+1为偶数(
2
k
2k
2k)时,此时的
x
x
x就是合法的,
而对应的
N
−
x
N-x
N−x就是
T
T
T。
枚举
x
x
x就是枚举
N
N
N的约数
时间复杂度:
O
(
N
)
O(\sqrt{N})
O(N)
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 100005
using namespace std;
typedef long long ll;
ll a[N], n;
int cnt;
int main()
{
scanf("%lld", &n);
for (ll i = 1; i * i <= n; i++)
if (n % i == 0)
{
if ((n / i + 1) % 2 == 0) a[++cnt] = n - i;
if (n / i != i) if ((i + 1) % 2 == 0) a[++cnt] = n - (n / i);
}
printf("%d", cnt - 1);
sort(a + 1, a + cnt + 1);
for (int i = 2; i <= cnt; i++) printf(" %lld", a[i]);
return 0;
}