P2759 奇怪的函式 題解
前置知識:
二分,對數。
簡要題意:
求 \(x^x\) 的位數超過或達到 \(n\) 位的最小的 \(x\).
\(n \leq 2 \times 10^9\).
首先,\(x^x\) 與 \(x\) 是正比例關係,具有單調性。樸素來說就是 \(x^x\) 隨 \(x\) 增大而增大,主要因為 \(x>1\).(答案不可能是 \(1\) 啊)
具有單調性的函式可以進行 二分答案。 可以用 \(\mathcal{O}(\log n)\) 的時間(其實不到 \(\log\),因為 \(x^x\) 位數大於 \(n\) 答案應該比 \(n\) 小的多,但是資料範圍就一個 \(n\)
即已知 \(x\) 和 \(n\),如何判斷 \(x^x\) 的位數是否超過 \(n\)?
下面我們要說一個函式,可以算出一個數的位數。
假設要算 \(a\) 的位數,同時存在 自然數 \(k\) 使得 \(10^k \leq a < 10^{k+1}\),則 \(a\) 是 \(k+1\) 位數。簡單來說,就是,在 \(10^3\) 和 \(10^4\) 之間除了 \(10^4\) 都是 \(4\) 位數,很顯然吧!
你會發現 \(\log_{10} 10^k = k , \log_{10} 10^{k+1} = k+1\),所以,\(\lfloor \log_{10} a \rfloor= k\)
這樣你會發現,\(\lfloor \log_{10} a \rfloor + 1\) 就是 \(a\) 的位數了!
那麼驗證就是 \(\lfloor \log_{10} a \rfloor + 1 \geq n\) 則達到(超過),否則就沒有達到。這樣的驗證是 \(\mathcal{O}(1)\) 的。
時間複雜度:\(\mathcal{O}(\log n)\).
實際得分:\(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; }