无限序列
无限序列
题目描述
我们按以下方式产生序列:
- 开始时序列是:
1
;- 每一次变化把序列中的
1
变成10
,0
变成1
。经过无限次变化,我们得到序列
1011010110110101101...
。总共有
个询问,每次询问为:在区间 和 之间有多少个 1
。任务:写一个程序回答
个询问。 输入格式
输入的第一行为一个整数 ,后面有
行,每行两个数用空格隔开的整数 。 输出格式
输出共
行,每行一个回答。 样例
样例输入
1
2 8样例输出
4
数据范围与提示
对于
的数据, , 。
-
做的时候先是手推到了变换8次后的结果试图找出循环节但是我失败了(
然后发现了第
次变换后的序列的前一部分就是第 次变换的序列然后就发现第
次变换后的序列的后一部分就是第 次变换的序列但是没发现这好像可以继续拆下去然后发现了第
次变换后的序列中有个斐波那契数列第i项个1然后甚至意识到了
区间内的1的数量等于 与 区间内的个数差然后我就不会了。。。
-
看了一些题解,终于发现这个序列是可以不断拆分到10和1的
//提前预处理出斐波那契数列1~99项的值 //f函数用于寻找第1~m之间1的个数 long long f(long long m){ if(m < 3) return n1[m]; //最好是从小往大找,因为这个序列是越拆越短的 for(int i = 3;i<=99;i++){ //如果长度正好等于预处理出的长度的第i项,那么1的个数也正好为对应的个数的第i项 if(le[i] == m) return n1[i]; //如果预处理出的长度第i项长于当前长度(即第一个长于长度的值),那么就接着拆后半部分 //拆完后得到的1的数量加上前半部分的1的数量即可 if(le[i] > m) return f(m-le[i-1]) + n1[i-1]; } }
-
举个栗子
下面是变换8次后的序列 1011 0101 1011 0101 1010 1101 1010 1101 10 n1 = [1,1,2,3,5,8 ,13,...] le = [1,2,3,5,8,13,21,...] 求在[3,18]区间内的1的数量 先求[1,18]区间内的1的数量 [1011 0101 1011 0101 10]10 1101 1010 1101 10 最短的长于14的完整序列长度为21 那么就可知最长的短于14的完整序列长为13 即 [1011 0101 1011 0]101 1010 1101 1010 1101 10 因此[1,18]区间内的1的数量为[1,13]与[14,18]之间的1的数量和 通过查询可知,[1,13]区间内有8个1 接下来将[14,18]拆分为[14,17]与[17,18]这两个完整序列 即[14,18]间1的数量为以下两部分完整序列的和: [14,17]这个长为3的完整序列中的1的数量 [17,18]这个长为2的完整序列中的1的数量 因此,[14,18]间的1的数量为2+1=3个 因此[1,18]区间内有8+3=11个1 同理可知[1,2]区间内有1个1 所以[3,18]间有11-1=10个1
还有就是
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库