打表、找规律
Chivas-Regal
#
# 牛客2021多校(3)E_Math
# 🔗
# 💡
看柿子,好乱啊,而且是最没有什么性质可言的可约符
看样例,数不多啊,打个表看一下都是谁
首先发现 是满足的
然后发现出现在一组里面第二个的,也会出现在别的组里面第一个
挖出来一条链看一下性质:
到 最接近是乘 ,然后减 ,用同乘规律试一下
然后再看
到 最接近是乘 ,然后减 ,同样同乘试一试
也满足,然后发现乘的都是第一个数的二次幂,试一下第一个数 的情况,也满足,那太好了
于是我们可以通过这种链处理出来所有 的二元组,也不多
在得答案时不能一个个找,毕竟如果 ,那么 个答案还是至少有的,结合 ,就会超时
但是用 来看,我们只要保证 ,故将所有的二元组 以 的大小排序,然后最后统计一下不大于 的数量即可,lower_bound
# ✅
struct node {
ll x, y;
inline node (ll _x, ll _y) {x = _x; y = _y;}
inline friend bool operator < (node a, node b) {
return a.y < b.y;
}
};
vector<node> res;
inline void Solve () {
ll n; cin >> n;
cout << upper_bound(res.begin(), res.end(), node(n, n)) - res.begin() << endl;
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr);
res.push_back({1, 1});
for (ll x = 2; x <= 1000000; x ++) {
res.push_back({x, x * x * x});
vector<ll> a;
a.push_back(x); a.push_back(x * x * x);
while (1) {
__int128_t nxt = (__int128_t)a.back() * x * x - a[a.size() - 2];
if (nxt <= 1000000000000000000)
res.push_back({a.back(), (ll)nxt}),
a.push_back(nxt);
else
break;
}
}
sort(res.begin(), res.end());
int cass; cin >> cass; while ( cass -- ) {
Solve ();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38