打表、找规律

#


# 牛客2021多校(3)E_Math

# 🔗

20220919192031

# 💡

看柿子,好乱啊,而且是最没有什么性质可言的可约符
看样例,数不多啊,打个表看一下都是谁
首先发现 (x,x4)(x,x^4) 是满足的
然后发现出现在一组里面第二个的,也会出现在别的组里面第一个
挖出来一条链看一下性质:
283011241815605822...2\;8\;30\;112\;418\;1560\;5822...
883030 最接近是乘 44 ,然后减 22 ,用同乘规律试一下
8×42=3030×48=112112×430=418...8\times 4-2=30\\30\times 4-8=112\\112\times 4-30=418\\...
然后再看
327240213318957168480...3\;27\;240\;2133\;18957\;168480...
2727240240 最接近是乘 99 ,然后减 33 ,同样同乘试一试
27×93=240240×927=2133...27\times 9-3=240\\240\times 9-27=2133\\...
也满足,然后发现乘的都是第一个数的二次幂,试一下第一个数 44 的情况,也满足,那太好了
于是我们可以通过这种链处理出来所有 1xy10181\le x\le y\le 10^{18} 的二元组,也不多

在得答案时不能一个个找,毕竟如果 n=1018n=10^{18} ,那么 10610^6 个答案还是至少有的,结合 TT ,就会超时
但是用 xyx\le y 来看,我们只要保证 yny\le n ,故将所有的二元组 (x,y)(x,y)yy 的大小排序,然后最后统计一下不大于 (n,n)(n,n) 的数量即可,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

Last Updated: 10/14/2023, 7:51:49 PM