遗憾题
每当思考完一道题目的时间效率,小Q就需要结合时限以及评测机配置来设置合理的数据范围。
因为确定数据范围是一件痛苦的事,小Q出了非常多的题目之后,都没有它们设置数据范围。对于一道题目,小Q会告诉你他的算法的时间复杂度为 O(nalogbn),且蕴含在这个大 O记号下的常数为 1。同时,小Q还会告诉你评测机在规定时限内可以执行 k条指令。小Q认为只要 na(⌈log2n⌉)b不超过 k,那么就是合理的数据范围。其中, ⌈x⌉表示最小的不小于 x的正整数,即 x上取整。
自然,小Q希望题目的数据范围 n越大越好,他希望你写一个程序帮助他设置最大的数据范围。
每组数据包含一行三个正整数 a,b,k(1≤a,b≤10,106≤k≤1018),分别描述时间复杂度以及允许的指令数。
解题思路:一开始知道方法是二分,但二分一直没写对,不知道哪里错了,后来去掉了等号就过了,但是此时比赛已结束,所以比较遗憾。。。
在写二分判断时,要用除法,因为乘法判断会爆 long long数据;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<math.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
//#define mod 10007
using namespace std;
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
long long a,b,k;
long long judge(long long num)
{
long long sum=1,a0=a,b0=b;
long long temp1=1,temp=1,i=0;
while(temp<num)
{
temp*=2;
i++;
}
while(b0--){
if(k/temp1<i)
return k+1;
temp1*=i;
}
while(a0--){
if(k/temp1<num)
return k+1;
temp1*=num;
}
return temp1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&a,&b,&k);
long long l=0,r=1e18+2,m,n;
long long mid=(l+r)/2;
while(l<r)
{
m=judge(mid);
if(m<k)
{
n=mid;
l=mid+1;
}
else if(m==k)
{
break;
}
else {
r=mid-1;
}
mid=(l+r)/2;
}
while(judge(n)<=k)
n++;
printf("%lld\n",n-1);
}
return 0;
}