题解 P2810 【Catch the theives】

题意简述:

定义一个合法的四元组(;(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;
}
原文地址:https://www.cnblogs.com/MIKU5201314/p/14086760.html