题目链接
https://ac.nowcoder.com/acm/contest/11254/E
题目大意
Given n, count the number of pairs of positive integers (x, y), such that
x
y
+
1
∣
x
2
+
y
2
,
1
≤
x
≤
y
≤
n
xy+1|x^2 + y^2,1≤x≤y≤n
xy+1∣x2+y2,1≤x≤y≤n.。
求小于n等于的满足以上条件的数的组数
题解
一开始看到数据在 1 0 18 10^{18} 1018就知道连 O ( n ) O(n) O(n)都跑不了,就输出前两万组强行找规律。
1 1
2 8
3 27
4 64
5 125
6 216
7 343
8 30
8 512
9 729
10 1000
11 1331
12 1728
13 2197
14 2744
15 3375
16 4096
17 4913
18 5832
19 6859
20 8000
21 9261
22 10648
23 12167
24 13824
25 15625
26 17576
27 240
27 19683
30 112
64 1020
112 418
125 3120
216 7770
240 2133
343 16800
418 1560
1020 16256
1560 5822
2133 18957
发现
x
,
x
3
x,x^3
x,x3是行得通的,代入原式也可以计算出。还有几组毒瘤如
8
,
30
8,30
8,30通过联系上下也可得出一组数的尾数也是另一组的首数,再代入求解一元二次方程即可得出尾数的代数式。
故满足条件的数为
x
,
x
3
x,x^3
x,x3和
x
3
,
.
.
.
.
.
.
x^3,......
x3,......。
最后将其进行排序,通过upper_bound计算即可得出结果。
参考代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e6+5;
long long f[N],t=0;
int main()
{
for(long long i=2;i*i*i<=1e18;i++)
{
ll x=i,y=i*i*i;
f[++t]=y;
while(y<=(1e18+x)/i/i)
{
x=i*i*y-x;
swap(x,y);
f[++t]=y;
}
}
sort(f+1,f+t+1);
int T;
cin>>T;
while(T--)
{
long long n;
scanf("%lld",&n);
printf("%lld\n",upper_bound(f+1,f+t+1,n)-f);
}
}
总结
如同它的名字,这是一道数学题,找规律+打表,据出题人说是签到题。。。