解决思路: 观察题意,用
x
\small x
x表示
y
\small y
y。
∴
y
=
n
x
x
−
n
(
x
−
n
∣
n
x
)
\small \therefore y=\frac{nx}{x-n}{~(x-n\mid nx)}
∴y=x−nnx(x−n∣nx) 此时,会发现这个式子不好计算,所以考虑用一个参数
t
\small t
t将
x
,
y
,
n
\small x,y,n
x,y,n联系起来。 令
t
=
x
−
n
\small t=x-n
t=x−n,
y
=
n
(
n
+
t
)
t
(
t
∣
n
2
+
n
t
)
\small y=\frac{n(n+t)}{t}~(t\mid n^2+nt)
y=tn(n+t)(t∣n2+nt)
∴
y
=
n
+
n
2
t
(
t
∣
n
2
)
\small \therefore y=n+\frac{n^2}{t}~(t\mid n^2)
∴y=n+tn2(t∣n2),
x
=
n
+
t
\small x=n+t
x=n+t
y
\small y
y的个数就是
n
2
\small n^2
n2的因子的个数,通过对
n
2
\small n^2
n2求因子个数肯定超时,所以考虑唯一分解。
n
=
p
1
q
1
p
2
q
2
.
.
.
p
n
q
n
\small n=p_1^{q_1}p_2^{q_2}...p_n^{q_n}
n=p1q1p2q2...pnqn,
n
2
=
(
p
1
q
1
p
2
q
2
.
.
.
p
n
q
n
)
2
\small n^2=(p_1^{q_1}p_2^{q_2}...p_n^{q_n})^2
n2=(p1q1p2q2...pnqn)2
n
2
\small n^2
n2的因子个数等于
(
2
q
1
+
1
)
(
2
q
2
+
1
)
.
.
.
(
2
q
n
+
1
)
\small (2q_1+1)(2q_2+1)...(2q_n+1)
(2q1+1)(2q2+1)...(2qn+1),
q
1
,
q
2
.
.
.
q
n
\small q_1,q_2...q_n
q1,q2...qn可通过对
n
\small n
n用试除法算出,
n
2
\small n^2
n2的因子个数就可得到。
∵
x
≤
y
\small \because x\leq y
∵x≤y
∴
n
+
t
≤
n
+
n
2
t
\small \therefore n+t\leq n+\frac{n^2}{t}
∴n+t≤n+tn2
→
~\small \rightarrow~
→
t
≤
n
\small\small t\leq n
t≤n 所以答案就是
n
2
中
\small n^2中
n2中小于等于
n
\small n
n的因子个数就是
n
2
\small n^2
n2的因子个数对
2
\small 2
2上取整
(
\small(
(且
n
2
\small n^2
n2的因子个数为奇数
)
\small )
)。
AC代码
//优化#pragma GCC optimize(2)//C#include<string.h>#include<stdio.h>#include<stdlib.h>#include<math.h>//C++//#include<unordered_map>#include<algorithm>#include<iostream>#include<istream>#include<iomanip>#include<climits>#include<cstdio>#include<string>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>//宏定义#define N 2010#define DoIdo main//#define scanf scanf_s#define it set<ll>::iterator//定义+命名空间typedeflonglong ll;typedefunsignedlonglong ull;const ll mod =998244353;const ll INF =1e18;constint maxn =5e6+10;usingnamespace std;//全局变量constdouble pi =acos(-1);//函数区
ll max(ll a, ll b){return a > b ? a : b;}
ll min(ll a, ll b){return a < b ? a : b;}//主函数intDoIdo(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);int T;
cin >> T;while(T--){int n;
cin >> n;int ans =1;for(int i =2; i * i <= n; i++){if(n % i ==0){int cnt =0;while(n % i ==0){ n /= i; cnt++;}
ans *=(cnt *2+1);}}if(n >=2) ans *=3;
cout << ans /2+1<< endl;}return0;}//分割线---------------------------------QWQ/*
*/