题意简述:
定义一个合法的四元组(;(x,k imes x,k^2 imes x,k^3 imes x);)满足:
- (;1leq k)。
- (;k^3 imes xleq m)。
现在给定合法的四元组数量(;n),求满足条件的最小的(;m)。
分析:
我们可以很容易的知道,一个四元组是否合法,只与其中的(;k^3 imes x;)有关,若(;k^3 imes xleq m),那么这个四元组也就合法了。
我们又得知,(;n;)的范围很大,高达(;10^{15}),总时间复杂度的角度来看,我们熟知的且常用的可以满足这个范围的只有(;O(log;n) O(sqrt n);)和(;O(1);)判断了。
我们发现,这个答案是具有单调性的,当(;m;)越大时,合法的四元组数量(;n;)也就越多。所以我们可以尝试对这个(;m;)进行二分。对于每一个(;m),最多只有(;leftlfloordfrac{n}{k^3} ight floor;)个合法的(;x),对于每一个(;m),我们可以在(;O(n^{frac{1}{3}});)的时间内求出其合法的方案数。
总时间复杂度为(;O(n^{frac{1}{3}} imes log;n)),可以通过此题。
还有一点需要注意的是,当我们二分出最后的答案时,输出前还需判断其合法的方案数是否为(;n),因为我们的二分是当其方案数大于等于(;n;)时记录的,因此我们二分出的答案可能是方案数大于(;n;)的。
(Code):
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f3f3f3f3f
#define il inline
#define vocaloid(v) (v>='0'&&v<='9')
#define ll long long
template <typename T>
il void read(T &x)
{
x=0;char v=getchar();
while(!vocaloid(v)) v=getchar();
while(vocaloid(v)) {x=(x<<1)+(x<<3)+(T)v-'0';v=getchar();}
}
ll n,l,r,ans=inf,mid;
il ll check(ll x)
{
ll num=0;
for(ll i=2;i*i*i<=x;i++)
num+=x/(i*i*i);
return num;
}
int main()
{
read(n);
l=1;r=5000000000000000;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)>=n) ans=mid,r=mid-1;
else l=mid+1;
}
if(check(ans)==n) printf("%lld
",ans);
else puts("-1");
return 0;
}