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

本文介绍了一种基于斐波那契数列的无限序列,并提出了一种利用前缀和算法高效计算指定区间内特定字符数量的方法。通过递归求解前缀和,实现了快速响应大量查询请求的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DescriptionDescriptionDescription

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

InputInputInput

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

OutputOutputOutput

共Q行,每行一个回答

SampleSampleSample InputInputInput

1
2 8 

SampleSampleSample OutputOutputOutput

4 

HintHintHint

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

TrainTrainTrain ofofof ThoughtThoughtThought

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

CodeCodeCode

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值