10049 - Self-describing Sequence
Time limit: 3.000 seconds
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=34&page=show_problem&problem=990
Solomon Golomb'sselfdescribing sequence

is the only nondecreasing sequence of positive integers with the property that it contains exactlyf(k) occurrences ofkfor eachk. A few moments thought reveals that the sequence must begin as follows:
In this problem you are expected to write a program that calculates the value of f ( n ) given the value of n .
Input
The input may contain multiple test cases. Each test case occupies a separate line and contains an integern(
). The input terminates with a test case containing a value0fornand this case must not be processed.
Output
For each test case in the input output the value off(n) on a separate line.
Sample Input
100
9999
123456
1000000000
0
Sample Output
21
356
1684
438744
1. 如何構造一個增長速率較快的遞推式?
注意到f(n)增長緩慢,不妨利用其反函數g(n)=max{m | f(m)=n}(比如g(4)=8),然後再求一次反函數f(n)=min{k | g[k]>=n}即可得到f(n)。
随後由f(n)的定義有g(n)=g(n-1)+f(n)=g(n-1)+min{k | g[k]>=n}
(比如g(4)=g(3)+f(4)=5+3=8,g(5)=g(4)+f(5)=8+3=11)
2. 如何計算min{k | g[k]>=n}?
用二分查找。
完整代碼:
/*0.075s*/
#include<cstdio>
#include<algorithm>
const int M = 700000;
using namespace std;
long long g[M];
int main()
{
g[1] = 1;
g[2] = 3;
for (int i = 3; i < M; ++i)
g[i] = g[i - 1] + (lower_bound(g + 1, g + i, i) - g);
int n;
while (scanf("%d", &n), n)
printf("%d\n", lower_bound(g + 1, g + M, n) - g);
return 0;
}