P2759 奇怪的函数 题解

博客园同步

原题链接

前置知识:

二分,对数。

简要题意:

x x x^x 的位数超过或达到 n n 位的最小的 x x .

n 2 × 1 0 9 n \leq 2 \times 10^9 .

首先, x x x^x x x 是正比例关系,具有单调性。朴素来说就是 x x x^x x x 增大而增大,主要因为 x > 1 x>1 .(答案不可能是 1 1 啊)

具有单调性的函数可以进行 二分答案。 可以用 O ( log n ) \mathcal{O}(\log n) 的时间(其实不到 log \log ,因为 x x x^x 位数大于 n n 答案应该比 n n 小的多,但是数据范围就一个 n n ,这样分析也没啥问题)。那么如何验证答案呢?

即已知 x x n n ,如何判断 x x x^x 的位数是否超过 n n

下面我们要说一个函数,可以算出一个数的位数。

假设要算 a a 的位数,同时存在 自然数 k k 使得 1 0 k a < 1 0 k + 1 10^k \leq a < 10^{k+1} ,则 a a k + 1 k+1 位数。简单来说,就是,在 1 0 3 10^3 1 0 4 10^4 之间除了 1 0 4 10^4 都是 4 4 位数,很显然吧!

你会发现 log 10 1 0 k = k , log 10 1 0 k + 1 = k + 1 \log_{10} 10^k = k , \log_{10} 10^{k+1} = k+1 ,所以, log 10 a = k \lfloor \log_{10} a \rfloor= k .

这样你会发现, log 10 a + 1 \lfloor \log_{10} a \rfloor + 1 就是 a a 的位数了!

那么验证就是 log 10 a + 1 n \lfloor \log_{10} a \rfloor + 1 \geq n 则达到(超过),否则就没有达到。这样的验证是 O ( 1 ) \mathcal{O}(1) 的。

时间复杂度: O ( log n ) \mathcal{O}(\log n) .

实际得分: 100 p t s 100pts .

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}

inline void write(int x) {
	if(x<0) {putchar('-');write(-x);return;}
	if(x<10) {putchar(char(x%10+'0'));return;}
	write(x/10);putchar(char(x%10+'0'));
}

int main() {
	int n=read()-1,l=1,r=1e9; //为了方便 , 先把 1 减掉
	while(l<r) {
		int mid=(l+r)>>1;
		if(mid*log10(mid)<n) l=mid+1;
		else r=mid; //二分答案
	} printf("%d\n",r);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/bifanwen/article/details/107471571
今日推荐