Description
我们按以下方式产生序列: 1、 开始时序列是: “1” ; 2、 每一次变化把序列中的 “1” 变成 “10” ,”0” 变成 “1”。 经过无限次变化,我们得到序列”1011010110110101101…”。 总共有 Q 个询问,每次询问为:在区间A和B之间有多少个1。 任务:写一个程序回答Q个询问
Input
第一行为一个整数Q,后面有Q行,每行两个数用空格隔开的整数a, b。
Output
共Q行,每行一个回答
Sample Input
1
2 8
Sample Output
4
Data Constraint
【数据范围】 •1 <= Q <= 5000
•1 <= a <= b < 2^63
做法:观察可得,每次变化的数,和每次增加的1的个数都满足斐波那契数列,那我们暴力跑到第92个数(93就超 2^63),然后递归统计答案
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#define ll long long
#define rep(i, a, b) for(int i = a; i <= b; i++)
using namespace std;
ll q, a[93], b[93];
ll find(ll x, ll y)
{
if (x == 0) return 0;
if (a[y] == x) return b[y];
else if (a[y - 1] > x) return find(x, y - 1);
else if (a[y - 1] <= x) return b[y - 1] + find(x - a[y - 1], y - 2);
}
int main()
{
a[0] = 1, a[1] = 1;
b[1] = 1;
rep(i, 2, 92)
{
a[i] = a[i - 1] + a[i - 2];
b[i] = b[i - 1] + b[i - 2];
}
cin >> q;
int x, y;
while (q--)
{
cin >> x >> y;
cout << find(y, 92) - find(x - 1, 92) << endl;
}
}