【斐波那契】【递归】无限序列

D e s c r i p t i o n Description Description

我们按以下方式产生序列:
1、 开始时序列是: “1” ;
2、 每一次变化把序列中的 “1” 变成 “10” ,“0” 变成 “1”。
经过无限次变化,我们得到序列"1011010110110101101…"。
总共有 Q 个询问,每次询问为:在区间A和B之间有多少个1。
任务 写一个程序回答Q个询问

I n p u t Input Input

第一行为一个整数Q,后面有Q行,每行两个数用空格隔开的整数a, b。

O u t p u t Output Output

共Q行,每行一个回答

S a m p l e Sample Sample I n p u t Input Input

1
2 8 

S a m p l e Sample Sample O u t p u t Output Output

4 

H i n t Hint Hint

1 <= Q <= 5000
1 <= a <= b < 2^63

T r a i n Train Train o f of of T h o u g h t Thought Thought

首先看那个序列,可以发现它是按照斐波那契数列的形式递增的
然后我们就可以加入前缀和发现:
f [ a , b ] = q [ b ] − q [ a − 1 ] f[a,b]=q[b]-q[a-1] f[a,b]=q[b]q[a1]
然后用递归求前缀和就好了

C o d e Code Code

#include<cstdio>
#include<iostream>
using namespace std;
long long f[1005][2],Q; long long a,b;
long long work(long long x)
{
	if (x==0) return 0;
	for (int i=0; i<=100; ++i)
	{
		if (x==f[i][1]) return f[i][0];//看是否符合长度
		 else if (x<f[i][1]) return f[i-1][0]+work(x-f[i-1][1]);//继续递归
	}
}
int main()
{
	scanf("%lld",&Q);
	f[0][0]=1; f[0][1]=1;//f[0][0]为序列中1的个数
	f[1][0]=1; f[1][1]=2;//f[0][1]为序列的长度
	for (int i=2; i<=100; ++i)
	  f[i][0]=f[i-1][0]+f[i-2][0],f[i][1]=f[i-1][1]+f[i-2][1];
	for (int i=1; i<=Q; ++i)
	{
		scanf("%lld%lld",&a,&b);
		printf("%lld\n",work(b)-work(a-1));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值