题解 P2810 【Catch the theives】

题意简述:

定义一个合法的四元组\(\;(x,k\times x,k^2\times x,k^3\times x)\;\)满足:

  • \(\;1\leq k\)
  • \(\;k^3\times x\leq m\)

现在给定合法的四元组数量\(\;n\),求满足条件的最小的\(\;m\)

分析:

我们可以很容易的知道,一个四元组是否合法,只与其中的\(\;k^3\times x\;\)有关,若\(\;k^3\times x\leq m\),那么这个四元组也就合法了。

我们又得知,\(\;n\;\)的范围很大,高达\(\;10^{15}\),总时间复杂度的角度来看,我们熟知的且常用的可以满足这个范围的只有\(\;O(log\;n)\ O(\sqrt n)\;\)\(\;O(1)\;\)判断了。

我们发现,这个答案是具有单调性的,当\(\;m\;\)越大时,合法的四元组数量\(\;n\;\)也就越多。所以我们可以尝试对这个\(\;m\;\)进行二分。对于每一个\(\;m\),最多只有\(\;\left\lfloor\dfrac{n}{k^3}\right\rfloor\;\)个合法的\(\;x\),对于每一个\(\;m\),我们可以在\(\;O(n^{\frac{1}{3}})\;\)的时间内求出其合法的方案数。

总时间复杂度为\(\;O(n^{\frac{1}{3}}\times 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\n",ans);
	else puts("-1");
	return 0;
}
posted @ 2020-12-04 17:01  初雫  阅读(104)  评论(0)    收藏  举报