不等式

题目分析:首先对题目进行分析,首先我们得明白我们的求的是什么?
求的是n!!!假设这个n为16,我们如何去计算x^3 * y <=n 有多少个解?

解法:我们可以写一个循环去遍历尝试x的值(x^3<=n),由题意我们从2开始,8*y<=16 化简一下 y<=2 也就是说 如果当x=2的时候,y的解有2个。
(我们选择增长快的x遍历去求n是一个好技巧)
所以解的个数的算法就出来了,我们设解的个数为cnt ,根据y=n/x^3 即 cnt+= n / x^3 (for 循环 x^3<=n)

    for (ll x = 2; x*x*x <= n; x++)
    {
        cnt += n/(x*x*x);//y解的个数

    }

很明显,n和m成正比例关系,只有n越多,m的解才能越多,所以我们于要求的n,是线性关系。
线性关系求最大值??? 当然是二分呀 !
所以我们的解题思路是二分......

判断二分域m最小值是1,m越大n越大,所以n最小是8
我们的左区间l=8, 右区间为1e16(取个大的)

然后二分出答案就可以了,但是记得得在cnt==m时 特判一下,做一个标记或者去更新ans。这是为什么呢?看图
在这里插入图片描述

因为我们是不断去取最小值的过程,如果找到了当符合条件了,说明并非无解,我们一定得记录下来,表明我们找的到符合条件的。

再解释一下二分,我们不断向左逼近,最后只需要输出左端点即可。

#include<bits/stdc++.h>
using namespace  std;
typedef long long ll;
#define IOS ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll N = 100000 + 5;
const ll Mod = 1000000009;
const ll MX = 0x3f3f3f3f;
ll l = 1, r = 1e16 + 1;
ll  m;
ll judge(ll n)
{
    ll cnt = 0;
    for (ll x = 2; x * x * x <= n; x++)
    {
        cnt += n / (x * x * x);//y解的个数

    }
    return cnt;
}
int main()
{
    IOS;
    while (cin >> m)
    {
        l = 8, r = INF;
        ll ans = -1;
        bool flag = 1;
        while (l <= r)
        {
            ll mid = (l + r) >> 1;
            ll cnt = judge(mid);
            if (cnt >= m)
            {
                r = mid-1;
                if (cnt == m)flag = 0;
            }
            else
            {
                l = mid + 1;
            }
        }
        if (flag)cout << -1 << endl;
        else cout << l << endl;

    }
    return 0;
}