UVa 10049 Self-describing Sequence (自描述序列&二分递推)

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'sself­describing sequence$\langle f(1), f(2), f(3), \dots \rangle$is the only non­decreasing 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:


\begin{displaymath}\begin{array}{c\vert cccccccccccc}\mbox{\boldmath $n$} & 1 &......)$} & 1 & 2 & 2 & 3 & 3 & 4 & 4 & 4 & 5 & 5 & 5 & 6\end{array}\end{displaymath}

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($1 \le n \le 2,000,000,000$). 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值