2656: [Zjoi2012]数列(sequence)
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 940 Solved: 481
[ Submit][ Status][ Discuss]
Description
小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式:
小白作为一个数学爱好者,很快就计算出了这个数列的通项公式。于是,小白告诉小蓝自己已经做出来了,但为了防止小蓝抄作业,小白并不想把公式公布出来。于是小白为了向小蓝证明自己的确做出来了此题以达到其炫耀的目的,想出了一个绝妙的方法:即让小蓝说一个正整数N,小白则说出 的值,如果当N很大时小白仍能很快的说出正确答案,这就说明小白的确得到了公式。但这个方法有一个很大的漏洞:小蓝自己不会做,没法验证小白的答案是否正确。作为小蓝的好友,你能帮帮小蓝吗?
Input
输入文件第一行有且只有一个正整数T,表示测试数据的组数。
第2~T+1行,每行一个非负整数N。
Output
输出文件共包含T行。
第i行应包含一个不含多余前缀0的数,它的值应等于An(n为输入数据中第i+1行被读入的整数)
【样例输入】
Sample Input
3
1
3
10
1
3
10
Sample Output
1
2
3
2
3
HINT
T<=20,N<=10^100
思路+暴力+python高精度
a[2i+1]=a[i]+a[i+1]
我们把a[i]和a[i+1]再拆开,发现式子中只有两个不同的数,一直拆下去,式子中就只剩x*a[1]+y*a[2],就可以出解。
时间为O(logn)
因此只要dfs(a,na,b,nb),na是a的个数,nb是b的个数。
def dfs(a,na,b,nb):
if (a==1):
return na+nb
if (a%2==0):
return dfs(a//2,na+nb,a//2+1,nb)
return dfs(b//2-1,na,b//2,na+nb)
T=raw_input()
T=int(T)
while (T>0):
T-=1
n=raw_input()
n=long(n)
if (n==0):
print 0
continue
while (n%2==0):
n//=2
x=n//2
if (x==0):
print 1
else:
print dfs(x,1,x+1,1)