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