P2759 奇怪的函数 题解

博客园同步

原题链接

前置知识:

二分,对数。

简要题意:

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

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

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

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

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

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

假设要算 a a a 的位数,同时存在 自然数 k k k 使得 1 0 k ≤ a < 1 0 k + 1 10^k \leq a < 10^{k+1} 10ka<10k+1,则 a a a k + 1 k+1 k+1 位数。简单来说,就是,在 1 0 3 10^3 103 1 0 4 10^4 104 之间除了 1 0 4 10^4 104 都是 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 log1010k=k,log1010k+1=k+1,所以, ⌊ log ⁡ 10 a ⌋ = k \lfloor \log_{10} a \rfloor= k log10a=k .

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

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

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

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

#pragma GCC optimize(2)
#include
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;
}


你可能感兴趣的:(二分,二分答案,对数)