不等式
题目分析:首先对题目进行分析,首先我们得明白我们的求的是什么?
求的是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;
}
京公网安备 11010502036488号