E题:Math
题目链接 https://ac.nowcoder.com/acm/contest/11254/E
题目大意
给定n( 1 ≤ n ≤ 1 0 18 1\leq n \leq 10^{18} 1≤n≤1018),求正整数对(x,y)满足 x 2 + y 2 是 x y + 1 的 整 数 倍 x^2+y^2是xy+1的整数倍 x2+y2是xy+1的整数倍的数量。( 1 ≤ x ≤ y ≤ n 1\leq x \leq y \leq n 1≤x≤y≤n)
思路
设
x
2
+
y
2
=
k
(
x
y
+
1
)
x^2+y^2=k(xy+1)
x2+y2=k(xy+1)
由韦达定理
(
x
,
k
x
−
y
)
(x,kx-y)
(x,kx−y) 为一组解。对于该
k
k
k,绝对值最小的一组正整数解一定满足
k
x
−
y
=
0
kx-y=0
kx−y=0 。可以发现这组解具有
(
x
,
x
3
)
(x,x^3)
(x,x3)的形式,则
k
=
x
2
k=x^2
k=x2。
其余解通过
k
x
−
y
kx-y
kx−y可求出。题目有
t
(
1
≤
t
≤
1
0
5
)
t (1\le t\le 10^5)
t(1≤t≤105)组数据,所以排序后对于每次查询,用二分求出即可。
代码实现
#include<bits/stdc++.h>
using namespace std;
unsigned long long n,sum=1;
const int N=5000010;
long long p[N];
int k;
int main(){
p[0]=1;
scanf("%d",&k);
for(long long i=2;i*i*i<=1e18;i++)
{
long long a=i,b=i*i*i,t;
p[sum++]=b;
while(b<=(1e18+a)/i/i){
t=b;
b=b*i*i-a;
a=t;
p[sum++]=b;
}
}
sort(p,p+sum);
while(k--)
{
scanf("%lld",&n);
int ans=upper_bound(p,p+sum,n)-p;
printf("%d\n",ans);
}
return 0;
}