无聊的函数(二分查找+数论)

来源:互联网 发布:linux中echo命令详解 编辑:程序博客网 时间:2024/06/05 02:18

无聊的函数
时空限制:1s,128MB
数据规模:1<=n<=2000000000
题目描述
定义一个函数:
f(x)=x^x (k=1)
f(x)=(x^x)^x (k=2)
其中 k 为给定的值(1 或 2)。
使得 f(x) 达到或超过 n 位数字的最小正整数 x 是多少?
此题由Luogu P2759 奇怪的函数 改装而来,题目难度上升了一点点。
思路:
对于函数f(x)的位数,可以用lg(x^x)表示,即:lg(x^x)=xlgx
类比的,lg((x^x)^x)=xlg(x^x)=x*xlg(x)
所以这个题可以用二分查找,(1,2000000000)区间查询,时间复杂度为log(2000000000)<40,具有非常优秀的时间复杂度。不知道为什么这个题在Luogu上是【提高+/省选-】难度的,可能是数论难度大的缘故吧。还有还有,luogu只问了当k=1的情况,这个题只要知道指对数相关转换公式的话,就是一枚水题,虽然不大好想。
代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>#include<cmath>using namespace std;int i,j,m,n,k,temp,now;int a[100001];int r(){    int ans=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9')    {        if(ch=='-')        f=-1;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        ans*=10;        ans+=ch-'0';        ch=getchar();    }    return ans*f;}long long func(long long x){    if(k==1)    return floor(x*log10(x));    if(k==2)    return floor(x*x*log10(x));}long long erfen(long long le,long long ri){    long long mid,fm,last=0;    while(le<=ri)    {        mid=(le+ri)/2;        fm=func(mid);        if(fm>n) ri=mid;        else if(fm<n) le=mid;        else return mid;        if(mid==last)        break;        last=mid;    }    return ri;}int main(){    freopen("func.in","r",stdin);    freopen("func.out","w",stdout);    n=r(),k=r();    n--;    cout<<erfen(1,2000000000);    return 0;} 

这里写图片描述

原创粉丝点击